新增依赖User抽象类的类:选择继承还是组合复用?
建议:继承还是组合?结合你的User抽象类分析
嘿,我来帮你梳理下这个决策——到底是用继承还是组合来复用你的User抽象类。先得明确这两种方式的核心区别,再结合你的场景来判断:
核心判断原则:"is-a" vs "has-a"
这是业界最经典的决策依据,先搞清楚这个就不会乱:
- 如果你的新类本质上就是一种User(比如
RegisteredUser、AdminUser这类角色),那用继承("is-a"关系)更合适 - 如果你的新类只是需要用到User的功能/数据,但本身不是User(比如
UserNotificationSender、AccountAuditor这类服务类),那组合("has-a"关系)才是正确选择
结合你的User抽象类具体分析
先把你给出的代码整理修正(补全了语法细节):
import java.io.Serializable; import java.util.Date; public abstract class User implements Serializable { protected String userName; protected String emailAddress; protected Date dob; protected Password password; // Initialisation Constructor public User(String userName, String emailAddress, int d, int m, int y, String cPW, String uEPW, int noTries){ this.userName = userName; this.emailAddress = emailAddress; this.dob = new Date(d, m, y); this.password = new Password(cPW, uEPW, noTries); } // Assume that User also has: // 1. a toString() method, // 2. an equals() method, and // 3. appropriate set() and get() methods }
适合用继承的场景
如果你的新类符合以下情况,果断选继承:
- 新类需要拥有
User的所有属性(用户名、邮箱、生日、密码),并且要扩展用户的专属行为(比如管理员的权限控制、会员的积分逻辑) - 新类需要被当作
User来使用(比如在接收User参数的业务方法中,能直接传入新类实例,符合里氏替换原则) - 典型例子:
AdminUser extends User、MemberUser extends User——这些角色本质上都是用户的细分类型
适合用组合的场景
如果你的新类符合以下情况,优先考虑组合:
- 新类只需要调用
User的部分方法,或者只是持有用户数据来完成自己的任务,本身和用户不是同一类事物 - 你想避免继承带来的强耦合(比如后续
User修改protected属性或方法,可能会影响所有子类),或者需要灵活替换用户相关的实现 - 典型例子:
UserMessageService(需要持有User对象发送消息,但它是服务类不是用户)、UserReportGenerator(需要用户数据生成报表,但不是用户)
额外的实用考量
- 继承的局限性:Java是单继承机制,一旦继承了
User,你的新类就不能再继承其他类;而且User的protected成员如果后续调整,子类可能会出现意想不到的问题 - 组合的灵活性:可以给
User定义一个接口(比如IUser),让新类依赖接口而非抽象类,这样后续可以灵活替换不同的用户实现,扩展性更强 - 里氏替换原则检查:如果选继承,一定要确保子类可以完全替代父类,不会破坏原有业务逻辑(比如子类重写方法时不能改变父类的预期行为)
总结下来,先想清楚你的新类和User到底是"是一种"还是"有一个"的关系,这个决策就清晰多啦!
内容的提问来源于stack exchange,提问作者D.Doherty
相关产品推荐
相关产品推荐

