读书笔记-《Effective Java》第16、17条:复合与继承

第16条:复合优于继承

  • 如果两个类的关系是 is-a,请选用继承。例如:男人/女人 与 人类的关系。
  • 如果两个类的关系是has-a,请选用复合。例如:腿毛 与 人类的关系。

不恰当的继承会出现错误,不只是优雅不优雅的问题。

例如:

public class Son2<E> extends HashSet<E> {

    public int count = 0;

    public Son2(Set s ) {

    }

    @Override
    public boolean add(E o) {
        count++;
        return super.add(o);
    }

    @Override
    public boolean addAll(Collection c) {
        count += c.size();
        return super.addAll(c);
    } 
}

在此程序中, 如果调用addAll方法,count分别会在addAll和add方法中计算, 因为父类HashSet的addAll会执行add方法, 而子类又重写了add方法。

而Son2类只是想使用父类的方法, 它们的关系并不是父子关系,所以最合适的是使用复合。

例如:

public class Son3<E> {

    public int count = 0;
    private Set s;

    public Son3(Set s) {
        this.s = s;
    }

    public boolean add(E o) {
        count++;
        return s.add(o);
    }

    public boolean addAll(Collection c) {
        count += c.size();
        return s.addAll(c);
    }


}

让Set成为类成员,被调用的add和addAll方法也不会覆盖Set的方法。

也可以专门新建一个类来转发(转发类),转发类也可以继承Set,把所有接口都转发。

类也可以包含多个这样的成员, 像不像Controll层调用多个Serivce层?

第17条: 要么为继承而设计,并提供文档说明,要么就禁止继承

如果类为继承而设计, 那么请提供详细的文档说明,要说明方法的用途(包括被子类重写后的影响),而不是实现过程;还要提供合适的钩子方法,在测试的唯一方式方法就是编写子类,发布前必须编写子类测试。

钩子方法是专门留给子类去实现的,并无方法体,例如:

父类:

子类: 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值