Java 组合与继承
面向对象:组合与继承
继承的本质是避免重复
程序员的宿命就是复制粘贴? 真的只能这样吗?
DRY原则/事不过三,三则重构
继承的本质就是提炼公用的代码,避免重复
Java的继承体系与Object中的常用方法
java是单根继承的
object的equals是判断两个对象是不是同一个对象。 很多时候并不满足我们想要的功能,可以通过IDEA的 自动生成来生成自定义的equals方法。注意Effective Java 里面说了,覆盖equals方法的同时也要覆盖hashcode方法
‘==‘判断两个对象的地址是否一样,equals判断两个对象包含 的内容是否一样
继承中的类结构与初始化顺序
子类拥有父类的一切行为和数据
父类先于子类
必须拥有匹配的构造器,super关键字
实例方法的覆盖
继承父类的时候,对某些功能不满意,用自定义的代码来覆盖父类的代码。 覆盖的方法签名是一样的,只是方法内部实现不同
永远使用@Override来防止手残,防止覆盖的方法名没有写对
设计模式实战:模板方法
一个类定义一些基础的方法,其他的类继承这个类(模板),任意覆盖 其中的部分或全部方法,通过这一个模板来衍生出很多不同的功能实现
Spring启动的过程就用到了模板方法(需要看Spring源码)
向上/向下转型
一个子类型的对象永远是一个父类型的对象
instance of 来判断类型,null instance of anything == false
final关键字与单例模式
final可以用在类,方法,类变量,参数,局部变量上面,代表只能赋值一次。
当final修饰对象的时候,对象的地址是不能改变的,但是对象本身是可以改变的。
当final修饰类的时候,类不能被继承。现实中的例子比如String,Integer,Boolean, 但是hashmap是没有final修饰符的。为什么? effective java里面写了一个类要么 就是可以继承,提前设计好,要么就不能继承。final类的好处是杜绝了继承的隐患- 子类破坏了父类的一些约定,这样父类是确定的
当final修饰方法的时候,方法不能被覆盖。final方法的好处是没有多态,这样 虚拟机可以把方法内联了,提高性能,不需要在运行时查找到底是哪个子类对应的方法
final的好处之一是线程安全性
单例模式举例,不是非常严格,即使构造器是private,也可以通过反射或者序列化与 反序列化来创造对象
public class World {
private static final World SINGLETON_INSTANCE = new World()
public static World getInstance() {
return SINGLETON_INSTANCE
}
private World() {}
}
课后题讲解(CountingSet),用例子说明,如果是继承的话,子类的代码非常依赖 父类的实现,从而破坏了封装性,好的封装是我不需要管实现细节的,但是如果 用组合的话,就不会有这个问题,组合里面只是调用了成员的方法,不会影响新 的类里面的计算结果,实现了隔离。这个例子出自effective java,组合由于继承