Effctive_Java--笔记&心得

equals && hashCode

  • 重写equals方法,只适合值类(枚举类除外)
  • 重新equals方法(普遍的等价关系),需遵循的约定:
    1. 自反性:x.equals(x)==true
    2. 对称性: x.equals(y)==true 必然 y.equals(x)==true
    3. 传递性: x.equals(y)==true, y.equals(z)==true 必然 x.equals(z)==true
    4. 一致性:多次执行结果一致。
  • 重写equals,必须重写hashCode, equals相等hashCode必须相等。hashMap,hashSet需要。

  • 无法再扩展可实例化类(写子类)的同时,既增加值组件,又保留equals约定

    1. 详见”代码-1”
    2. 解决方式:1,用组合代替继承。2,值组件加到抽象类中。
    3. 代码-1:
Piont p = Piont(x,y);
Point3D p3d = Point3D(x,y,z);
p.equals(p3d) == true;
p3d.equals(p) == false

封装、继承、组合(组合优于继承+自己的心得)

  • 封装:隐藏实现细节,改变细节而不影响接口/服务/使用
    1. 函数/方法是封装,类也是封装。
    2. 目的:解放精力在更高的层次上考虑和解决问题
  • 复用的两种方式:继承、组合
  • 继承的优缺点:
    1. 优点: 很方便的复用,比组合复用方便的多
    2. 缺点: 可能会破坏封装
  • 继承可能会破坏封装的分析:
    1. 子类依赖于父类的实现细节,子类在继承时需要关注父类的实现细节;父类在修改内部实现时,需要考虑对子类的影响。详见”代码-1”,”代码-2”
    2. 子类重写父类方法,可能会违背父类方法的声明
    3. 方法调用不会依赖实现细节,
  • 如何正确使用继承:
    1. 要么为继承而设计,并提供文档说明,要么就禁止继承–原书第17章
      • 文档必须说明每个可覆盖的方法的自用性
      • 文档必须精确地描述覆盖每个方法所带来的影响
      • 上述两条违背了”文档应该描述做什么,而不是怎么做”,这是继承破坏封装带来的恶果。
      • 构造器决不能调用可被覆盖的方法,无论是直接调用还是间接调用
      • 不可覆盖的方法: 使用final或者private修饰
      • 不可被继承的类: 使用final修饰类,private修饰所有构造(然后提供工厂方法)
  • 代码-2:
/**
 * 1,子类MyHashSet的addAll(),势必要考虑父类addAll()的实现细节。
 * 2,父类未来修改addAll()的内部实现,很可能会影响到子类的正确性。
 */
public class MyHashSet<E> extends HashSet<E>{
    private int addCount = 0;
    public boolean add(E e) {
        addCount++;
        return super.add(e);
    }
    /**
     * 父类,子类各自的实现细节及依赖:
     * <pre>
     *     1, 父类HashSet.addAll()-->父类HashSet.add()
     *     2, 子类MyHashSet.addAll()-->父类HashSet.addAll()-->子类MyHashSet.add() //因为多态
     * </pre>
     */
    public boolean addAll(Collection<? extends E> c) {
        addCount += c.size();
        return super.addAll(c);
    }
    public int getAddCount() {
        return addCount;
    }
    public static void main(String[] args) {
        MyHashSet<String> s = new MyHashSet<String>();  
        s.addAll(Arrays.asList("a", "b", "c"));
        //输出是6,不是3。  
        System.out.println(s.getAddCount());  
    }
}

其他准则

  • 始终覆盖toString
  • 使类和成员的访问下最小。以后再改大。
  • 接口优于抽象类
  • 接口只用于定义类型
  • 用类层次替代标签类
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值