如何设计含Name、Address子类的Person类?聊天室场景类拆分问询
Hey there! Let's walk through how to extend your Chatroom system by refactoring the Person class, adding Address-related structures, and building a Person class that includes Name and Address components. Here's a clear, step-by-step approach with code examples:
First, we'll create standalone Name and Address classes to follow the single responsibility principle—each class handles one specific set of data/behavior:
Name Class
This class manages all name-related logic:
public class Name { private String firstName; private String lastName; public Name(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } // Getters and Setters public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } // Optional: Make string output more readable @Override public String toString() { return firstName + " " + lastName; } }
Address Class
For address data, we can create a flexible class that holds standard address fields. If you need more granularity later, you could split this into subclasses (e.g., StreetAddress, City), but this base version works for most cases:
public class Address { private String street; private String city; private String zipCode; private String country; public Address(String street, String city, String zipCode, String country) { this.street = street; this.city = city; this.zipCode = zipCode; this.country = country; } // Getters and Setters public String getStreet() { return street; } public void setStreet(String street) { this.street = street; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } public String getZipCode() { return zipCode; } public void setZipCode(String zipCode) { this.zipCode = zipCode; } public String getCountry() { return country; } public void setCountry(String country) { this.country = country; } }
Instead of a single Person class, we'll create an abstract parent class for shared properties/methods, then split into concrete subclasses for different user types (e.g., regular users, admins). This makes the system easy to extend later.
Abstract Person Parent Class
This class defines core attributes and a required message-sending method:
public abstract class Person { protected Name name; protected Address address; protected Chatroom chatroom; public Person(Name name, Address address, Chatroom chatroom) { this.name = name; this.address = address; this.chatroom = chatroom; } // All Person subclasses must implement this method public abstract void sendMessage(String message, Person recipient); // Getters and Setters public Name getName() { return name; } public void setName(Name name) { this.name = name; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } public Chatroom getChatroom() { return chatroom; } public void setChatroom(Chatroom chatroom) { this.chatroom = chatroom; } }
RegularUser Subclass
For standard chat participants:
public class RegularUser extends Person { public RegularUser(Name name, Address address, Chatroom chatroom) { super(name, address, chatroom); } @Override public void sendMessage(String message, Person recipient) { chatroom.sendMessage(this, recipient, message); } }
AdminUser Subclass
For users with special privileges (like broadcasting messages):
public class AdminUser extends Person { public AdminUser(Name name, Address address, Chatroom chatroom) { super(name, address, chatroom); } @Override public void sendMessage(String message, Person recipient) { chatroom.sendMessage(this, recipient, message); } // Admin-only feature: Send message to everyone in the chatroom public void broadcastMessage(String message) { chatroom.broadcastMessage(this, message); } }
We'll adjust the Chatroom to manage the new Person hierarchy and handle both private and broadcast messages:
import java.util.ArrayList; import java.util.List; public class Chatroom { private List<Person> users; public Chatroom() { this.users = new ArrayList<>(); } // Add a user to the chatroom public void addUser(Person user) { users.add(user); user.setChatroom(this); } // Send a private message from sender to recipient public void sendMessage(Person sender, Person recipient, String message) { if (users.contains(sender) && users.contains(recipient)) { System.out.printf("[%s] → [%s]: %s%n", sender.getName(), recipient.getName(), message); } else { System.out.println("Error: Sender or recipient not in this chatroom!"); } } // Broadcast a message from sender to all users public void broadcastMessage(Person sender, String message) { if (users.contains(sender)) { System.out.printf("[%s] (Broadcast): %s%n", sender.getName(), message); for (Person user : users) { if (!user.equals(sender)) { System.out.printf(" ✅ Received by [%s]%n", user.getName()); } } } else { System.out.println("Error: Sender not in this chatroom!"); } } }
Here's a quick demo to show how all components work together:
public class ChatroomDemo { public static void main(String[] args) { // Create Name and Address instances Name aliceName = new Name("Alice", "Smith"); Address aliceAddr = new Address("123 Main St", "New York", "10001", "USA"); Name bobName = new Name("Bob", "Johnson"); Address bobAddr = new Address("456 Oak Ave", "Los Angeles", "90001", "USA"); Name charlieName = new Name("Charlie", "Brown"); Address charlieAddr = new Address("789 Pine Rd", "Chicago", "60601", "USA"); // Create chatroom and users Chatroom techChat = new Chatroom(); RegularUser alice = new RegularUser(aliceName, aliceAddr, techChat); RegularUser bob = new RegularUser(bobName, bobAddr, techChat); AdminUser charlie = new AdminUser(charlieName, charlieAddr, techChat); // Add users to chatroom techChat.addUser(alice); techChat.addUser(bob); techChat.addUser(charlie); // Test private message alice.sendMessage("Hey Bob, want to pair on the project later?", bob); // Test admin broadcast charlie.broadcastMessage("Reminder: Team sync at 3 PM today!"); } }
- Composition over inheritance: We used composition to give
Personaccess toNameandAddressinstead of making them subclasses. This keeps each class focused and avoids messy inheritance hierarchies. - Abstract parent class: The
Personabstract class ensures all user types follow a consistent interface for sending messages, making the system predictable. - Extensibility: Adding new user types (e.g.,
GuestUser) is as simple as creating a new subclass ofPerson—no need to rewrite core chatroom logic.
内容的提问来源于stack exchange,提问作者Mitchell Argamasilla

