Java笔记整理:复用类
复用代码最简单的方式就是复制代码
可以通过创建新类进行复用:
- 在新类中产生现有类的对象(组合)
- 按照现有类来创建新类(继承)
组合
每一个非基本类型的类都有一个toString方法
类中基本类型的域会自动初始化为0,对象引用初始化为null
null引用可以被打印
初始化引用的方式:
- 定义的地方。这将会在构造器之前执行
- 构造器中
- 正要使用之前。也叫惰性初始化
- 使用实例初始化
继承
创建一个类时,总是在继承。除非显式指出继承某类,否则将隐式继承Object类
继承将自动获得基类的所有域和方法
使用super关键字调用基类版本的域或方法
初始化基类
创建一个导出类的对象时,该对象会包含一个基类的子对象
导出类的构造器中自动先调用基类的构造器
构造过程是从基类向外扩散的,即先调用基类的,再调用导出类的。这使得基类内容在导出类可以访问它时,就已经完成了初始化
Java会调用的是基类的默认构造器,如果基类没有,需要用super显式地调用基类的带参构造器
调用基类构造器必须是导出类构造器中的第一件事
代理
代理是一个编程模式,是继承和组合的中庸之道
将成员对象置于类中(组合),在类中暴露成员对象的所有方法(类似继承),相当于新类代理了各个成员对象的行为
结合使用组合和继承
确保正确清理
由于不知道垃圾回收器何时回收,因此需要显式地遍写方法来进行收尾
可以使用try-finally代码块。无论try是如何退出的,finally块总会被执行
清理顺序应和构造顺序相反
不要使用finalize
名称屏蔽
在导出类中对基类的方法进行重载,不会屏蔽基类的所有重载版本 @Override
注解可以防止在不想重载时意外进行了重载
选择组合或继承
组合和继承都是在新类中放置子对象,组合是显式的,继承是隐式的
组合通常是希望在新类中使用现有类的功能,而并非得到其接口。用户看到的只有新类的接口,而看不到成员的接口
继承是希望使用现有类,开发它的特殊版本
- 组合 = has-a
- 继承 = is-a
protected
继承使protected关键字具有意义
应尽量使用private,然后用protected限制继承者的访问权限
向上转型
称为向上转型是因为,类层次关系中基类是上层的
向上转型总是安全的
向上转型会丢失信息
向上转型的过程中,类接口只会丢失方法,而不会获取方法
继承应当慎用,使用继承前应考虑是否需要进行向上转型
final关键字
final数据
final的作用是向编译器通知一块数据是恒定不变的
- 永不改变的编译时常量
- 运行时初始化的值,希望不被改变
JAVA会对final使用优化进行优化,对于域会在编译时计算表达式,对于方法会使用内嵌机制
编译时常量必须是基本类型,定义该常量时必须对其进行赋值
final修饰对象引用时,表示该引用恒定不变。一旦该引用指向一个对象,就不能指向别的对象
JAVA编写规范中,既是static又是final的域命名用大写,用下划线分隔单词
空白final
声明为final但没有给定初值的域
无论如何,必须在域的定义处或每个构造器中对final进行赋值,否则将会在使用该域时产生异常
final参数
表示无法在方法中更改参数的值或指向的对象
final方法
使用final方法的原因:
- 锁定方法,防止导出类修改其含义
- 效率。使用内嵌调用提高效率
类中的private方法都隐式地指定为final
覆盖一个private方法不会导致错误,但不会覆盖,而是产生了一个新方法
final类
表示无法被继承
类中的所有方法都隐式指定为final
初始化以及类的加载
编译代码文件只有在需要使用时才会被加载
加载发生于创建类的第一个对象或者访问静态域或方法时
所有的静态域和代码段都会在加载时,按照书写顺序依次初始化
在使用导出类时,会加载基类
对于静态成员,会先初始化基类的