发布时间:2023-02-13 文章分类:编程知识 投稿人:李佳 字号: 默认 | | 超大 打印

读Java实战(第二版)笔记08_默认方法

1.兼容性

1.1.二进制级的兼容性

1.1.1.只要不重新编译该类,即使不实现新的方法,现有类的实现依旧可以运行

1.1.2.现有的二进制执行文件能无缝持续链接(包括验证、准备和解析)和运行

1.1.3.如果新添加的方法不被调用,接口已经实现的方法就可以继续运行,不会出现错误

1.2.源代码级的兼容性

1.2.1.引入变化之后,现有的程序依然能成功编译通过

1.3.函数行为的兼容性

1.3.1.变更发生之后,程序接受同样的输入能得到同样的结果

2.向接口添加方法是罪恶之源

2.1.二进制级的兼容性

2.2.不是源码级的兼容

2.2.1.因为遗留代码并没有实现新引入的方法,所以它们无法顺利通过编译

2.3.函数行为的兼容性

2.3.1.因为新添加的方法在程序中并未被调用,抑或该接口在实现中被覆盖了

3.接口声明方法的2种实现

3.1.静态方法

3.1.1.静态方法可以存在于接口内部

3.1.1.1.辅助类就没有了存在的必要

3.2.默认方法

3.2.1.指定接口方法的默认实现

3.2.1.1.让类可以自动地继承接口的一个默认实现

3.2.1.2.不显式地提供该方法的具体实现,就会自动继承默认的实现

3.2.2.default修饰符

4.为API创建不同的发布版本,同时维护老版本和新版本

4.1.增加了作为类库的设计者维护类库的复杂度

4.2.类库的用户不得不同时使用一套代码的两个版本

4.2.1.项目使用的类文件数量更多了

4.2.2.增大内存的消耗

4.2.3.延长程序的载入时间

4.3.费时费力的

5.默认方法

5.1.缺失的方法实现会作为接口的一部分由实现类继承(所以命名为默认实现),而无须由实现类提供

5.2.由default修饰符修饰,并像类中声明的其他方法一样包含方法体

5.3.函数式接口只包含一个抽象方法,默认方法是种非抽象方法

5.4.主要目标用户是类库的设计者

5.4.1.为接口的演进提供了一种平滑的方式

5.4.2.兼容的方式解决像Java API这样的类库的演进问题的

5.4.3.让类库的设计者放心地改进应用程序接口,无须担忧对遗留代码的影响

5.4.4.为方法的多继承提供了一种更灵活的机制

5.4.4.1.类可以从多个接口继承默认方法

5.4.4.2.帮助你更好地规划你的代码结构

5.5.使用模式

5.5.1.可选方法

5.5.1.1.类实现了接口,却刻意地将一些方法的实现留白

5.5.1.2.可以减少无效的模板代码

5.5.1.2.1.已经有一个默认的实现
5.5.1.2.2.不需要再声明一个空的方法

5.5.2.行为的多继承

5.5.2.1.构造Java语言中的多继承

5.5.2.2.Java的类只能继承单一的类

5.5.2.3.一个类可以实现多接口

5.5.2.3.1.类可以从多个接口中继承它们的行为(即实现的代码)

5.5.2.4.保持接口的精致性和正交性能帮助你在现有的代码基上最大程度地实现代码复用和行为组合

5.5.2.4.1.利用正交方法的精简接口
5.5.2.4.2.组合接口
5.5.2.4.3.通过精简的接口,你能获得最有效的组合,因为你可以只选择需要的实现

6.关于继承的错误观点

6.1.不应成为代码复用就试图倚靠的“万精油”

6.2.从一个拥有100个方法及字段的类进行继承就不是个好主意

6.2.1.使用代理有效地规避这种窘境

6.2.1.1.创建一个方法通过该类的成员变量直接调用该类的方法

6.2.2.声明为final的类不能被其他的类继承,避免发生这样的反模式,防止核心代码的功能被污染

7.解决冲突的规则

7.1.解决可能的二义性(模糊性)问题

7.1.1.菱形继承问题

7.1.1.1.一个类同时继承了具有相同函数签名的两个方法

7.2.类中的方法优先级最高

7.2.1.类或父类中声明的方法的优先级高于任何声明为默认方法的优先级

7.3.如果无法依据第一条进行判断,那么子接口的优先级更高

7.3.1.函数签名相同时,优先选择拥有最具体实现的默认方法的接口,即如果B继承了A,那么B就比A更加具体

7.4.如果还是无法判断,那么继承了多个接口的类必须通过显式覆盖和调用期望的方法,显式地选择使用哪一个默认方法的实现

7.4.1.引入了一种新的语法X.super.m(...),其中X是你希望调用的m方法所在的父接口

8.定义接口以及工具辅助类(companion class)是Java语言常用的一种模式

9.抽象类和抽象接口

9.1.一个类只能继承一个抽象类

9.2.一个类可以实现多个接口

9.3.一个抽象类可以通过实例变量(字段)保存一个通用状态

9.4.接口是不能有实例变量的