面向对象:组合与继承

继承的本质是避免重复

程序员的宿命就是复制粘贴? 真的只能这样吗?

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,组合由于继承