【小白学习系列】Java编程思想第8章趟坑笔记
2026/7/26 1:56:31 网站建设 项目流程

《Java编程思想》第8章(多态)全部反常识+高频易错点

1、向上转型:最普遍的认知误区

  1. 误区:向上转型丢失子类方法/成员
    反常识真相:对象本体永远是子类,只是引用的访问接口被收缩;重写方法动态执行子类逻辑,独有方法只是访问被屏蔽,对象本身所有数据、方法完好无损。
  2. 误区:继承是为了复用代码
    书本核心结论:继承设计首要目标是依靠向上转型实现多态、解耦代码;代码复用只是附带红利。
  3. 向上转型百分百安全隐式转换,向下强转必须配合instanceof校验,否则运行时报类型转换异常。

2、绑定机制:只有实例普通方法才有动态绑定(多态)

反常识清单

  1. static静态方法:无重写,只有静态遮蔽
    静态方法绑定引用类型,不看堆内真实对象;父类引用指向子类对象,调用静态方法永远执行父类静态代码,不存在多态。
  2. final、private方法:静态绑定(前期绑定)
    private默认等效final,子类写同名方法属于全新方法,并不是重写,编译期就绑定引用类型。
  3. 成员变量不存在多态
    变量编译期绑定引用类型,父类引用读取变量,永远拿到父类属性值,和实际子类对象无关。

3、构造器内部调用可重写方法:极易触发空指针(本章经典大坑)

  1. 构造执行顺序:父类构造 → 成员变量初始化 → 子类构造体
    父类构造方法执行时,子类的成员变量还完全没有初始化。
  2. 若父类构造器调用了被子类重写的实例方法,会直接执行子类重写代码,此时子类字段全是默认值,访问子类属性大概率NPE。
    硬性规范:构造方法中绝对不要调用可被重写的方法

NPE:NullPointerException,空指针异常,代码去访问 / 调用一个值为 null 的对象的属性、方法,程序直接报错崩溃。如下代码,父构造执行阶段,子类字段还是空的,多态强行执行子类方法,操作空变量,就触发空指针 NPE。

classFather{publicFather(){// 父构造调用可重写方法test();}publicvoidtest(){}}classSonextendsFather{Stringinfo;// 构造执行阶段 = null@Overridepublicvoidtest(){System.out.println(info.length());// info是null,执行直接NPE}}publicclassTest{publicstaticvoidmain(String[]args){newSon();}}

4、清理与继承、finalize误区

  1. 子类销毁时,不会自动执行父类清理逻辑,需要手动在子类清理方法中主动调用父类清理方法。
  2. finalize()依靠GC执行,GC时机不可控,不能用来释放文件、连接、句柄等系统资源;GC只管堆内存回收,和业务资源清理毫无关系。

5、抽象类 & 抽象方法易错点

  1. 包含抽象方法的类必须标记abstract;abstract类可以拥有普通成员变量、普通实例方法、构造器。
  2. 抽象类不能new实例,但是拥有构造方法,作用是给子类构造时完成父类成员初始化。
  3. 子类继承抽象类,必须实现全部抽象方法,否则子类自身也要声明为abstract。

6、向下转型 + RTTI(运行时类型识别)

  1. 编译器不会校验向下转型是否合法,只会在运行时校验真实对象类型,非法转型直接抛ClassCastException
  2. 标准安全写法:转型前先用对象 instanceof 目标类判断匹配关系,再做强转。
  3. 向上转型抹平了具体类型,想要取回子类独有功能,唯一合法手段就是安全向下转型。

RTTI:Run-Time Type Information,运行时类型信息
向上转型后,父类引用屏蔽了子类真实类型:
Animal animal = new Dog();
编译期只认为 animal 是 Animal,编译器看不到真实是 Dog。
等到运行时,JVM 依靠 RTTI 知晓:这个对象本体就是 Dog,我们才能安全向下转型。

Java 里两种 RTTI 体现形式:

  • 传统 RTTI(面向 Class 类)
    (Dog) animal 强制向下转型:运行时依靠 RTTI 校验类型,类型不符抛出ClassCastException
    animal instanceof Dog:运行时借助 RTTI 判断对象真实类型是否匹配
  • 反射机制,属于 RTTI 的高级形态

7、继承设计的反常识设计理念

  1. 优先用组合,而不是优先使用继承;继承用来描述「is-a」关系,组合描述「has-a」。
  2. 继承用来扩展行为、实现多态;单纯复用代码优先组合,过度继承会造成层级臃肿、耦合严重。
  3. 不要随意把类设计为可继承,不需要被重写的方法建议加final,关闭重写入口,规避构造器多态这类隐蔽bug。

8、private方法的“假重写”陷阱

父类private方法,子类定义一模一样签名的方法,语法不会报错,但并不是重写。
父类引用指向子类,调用该私有方法,执行的永远是父类私有方法;子类方法只是一个全新的独立方法,无任何重写特性。

题目巩固

第1题
单选:在父类的构造方法中调用一个可被子类重写的普通实例方法,会发生什么情况()
A. 执行父类原本的方法实现
B. 执行子类重写方法,子类成员变量已经完成初始化
C. 执行子类重写方法,子类成员变量为默认初始值,极易引发空指针异常
D. 编译直接报错禁止该写法
正确答案:C
解析:普通实例方法遵循动态绑定,父类构造执行时会运行子类重写代码;对象初始化顺序为先父类构造、再初始化子类属性、最后执行子类构造体,此时子类自定义变量均为默认值,引用类型为null,访问极易触发NPE;该写法编译不会报错,属于隐藏的运行时bug。

第2题
单选:Java中RTTI(运行时类型信息)的核心作用是()
A. 编译阶段提前校验父子类转型是否合法
B. 程序运行阶段识别对象真实的所属类型
C. 提升向上转型的运行效率
D. 让静态方法具备多态特性
正确答案:B
解析:向下转型的合法性校验不在编译期,依靠运行时RTTI完成校验;RTTI作用就是运行时判定对象真实类型,支撑instanceof、强制向下转型功能;RTTI和运行效率优化无关;静态方法为静态绑定,不支持多态。

第3题
单选:关于静态方法与重写,说法正确的是()
A. 子类重写父类静态方法,存在动态绑定,支持多态
B. 父类引用指向子类对象,调用静态方法,执行子类静态方法
C. 子类同名静态方法覆盖父类,该现象叫做静态遮蔽,无多态
D. private静态方法可以被子类正常重写
正确答案:C
解析:静态方法编译期静态绑定,不存在动态绑定与多态;静态方法跟随引用类型执行,父类引用只会执行父类静态方法;子类同名静态方法属于静态遮蔽,并非真正的方法重写;private方法对子类不可见,无法完成重写。

第4题
单选:向上转型的本质描述准确的是()
A. 将子类对象销毁,新建一份父类对象
B. 本体依旧是子类对象,只是引用的访问接口被缩小
C. 向上转型之后子类独有的方法被永久清除
D. 向上转型需要手动强制转换格式书写
正确答案:B
解析:向上转型不会销毁堆中的子类实体对象;仅通过父类引用屏蔽子类独有方法,方法本体依然存在,向下转型即可恢复调用;向上转型属于隐式自动转换,不需要强制书写代码。

第5题
单选:继承的首要设计目的是()
A. 复用父类已有代码,减少重复编码
B. 依靠向上转型实现多态,实现代码解耦与扩展
C. 方便子类扩充成员变量
D. 替代组合关系完成业务封装
正确答案:B
解析:代码复用只是继承带来的附加收益,并非语言设计继承的初衷;继承核心价值是依托向上转型实现多态,解耦程序结构;扩充属性、替代组合都不是继承的设计目标,开发优先使用组合。

第6题
单选:关于向下转型与RTTI,错误的说法是()
A. 向下转型语法编译能够通过,合法性依靠运行时RTTI校验
B. 搭配instanceof判断,本质就是借助RTTI获取对象真实类型
C. 向上转型丢失了子类对象本体数据,向下转型也无法复原
D. 未经判断直接强转类型不匹配时,运行抛出ClassCastException
正确答案:C
解析:向下转型仅做语法检查,真实类型校验交由运行时RTTI处理;instanceof底层依赖RTTI识别真实类型;向上转型只会收缩访问权限,子类完整数据、方法全部保留,合法向下转型即可正常使用子类功能;非法强制转型会抛出类型转换异常。

第7题
单选:抽象类相关规则正确的是()
A. 抽象类不能拥有构造方法
B. 抽象类中只能存放抽象方法,不能写普通实例方法
C. 子类继承抽象类,若不实现全部抽象方法,子类必须声明为abstract
D. 使用new关键字可以直接实例化抽象类对象
正确答案:C
解析:抽象类具备构造方法,作用是给子类初始化父类成员,只是无法直接实例化;抽象类可包含普通方法、成员变量、静态代码块等内容;未实现父类所有抽象方法的子类自身必须定义为抽象类;抽象类禁止使用new创建对象。

第8题
单选:关于父类private方法,子类书写一模一样方法签名的代码,下列说法正确的是()
A. 属于方法重写,具备多态特性
B. 不属于重写,只是子类全新的独立方法
C. 父类引用指向子类,会执行子类该私有同名方法
D. private方法默认动态绑定
正确答案:B
解析:父类私有方法对子类不可见,无法构成重写,不存在多态效果;子类同名方法只是自身独立方法,和父类私有方法互不干扰;父类引用只会执行父类的私有方法;private方法等同于final,采用静态绑定。

第9题
单选:面向对象设计原则中,类的功能复用优先选择下面哪一种方式()
A. 继承
B. 组合
C. 重写方法
D. 向上转型
正确答案:B
解析:《Java编程思想》规范:优先组合,谨慎使用继承;继承代表强耦合的is-a关系,仅适合描述从属关系,不适合单纯用来复用代码;重写、向上转型都不属于代码复用的基础方案。

第10题
单选:finalize方法以及资源释放的描述正确的是()
A. 依靠GC执行finalize关闭文件、数据库连接十分安全可靠
B. GC只会回收堆内存空间,不会主动释放操作系统各类资源
C. 调用System.gc()后,finalize方法必定立刻执行
D. 对象内存被回收,对应的文件句柄会被JVM自动释放
正确答案:B
解析:finalize执行时机不确定,甚至不会执行,严禁用来释放系统资源;GC只负责回收堆内存,文件句柄、网络连接等系统资源必须手动close关闭;System.gc()只是给JVM的回收建议,无法强制GC执行;内存回收不会同步释放系统句柄,会造成句柄泄漏问题。

链接:

《Java编程思想》重点章节+踩坑学习规划

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询