抽象类可有构造方法但不能实例化,其构造方法供子类通过super()调用以初始化共用状态;子类构造时必须先完成父类初始化,若父类无无参构造则须显式调用super(参数),否则编译失败。

继承中构造方法调用顺序与隐式 super() 的陷阱
子类构造方法执行前,必须完成父类初始化。Java 编译器会在子类构造方法首行自动插入 super(),前提是父类存在无参构造。一旦父类只提供有参构造,子类所有构造方法都必须显式写 super(参数),否则编译失败。
常见错误包括:
• 忘记在子类构造方法第一行写 super() 或 this()
• 同时出现 super() 和 this()(二者互斥)
• 父类构造中调用了被子类重写的方法(此时子类字段尚未初始化,可能为 null 或默认值,引发空指针或逻辑错误)
protected 与默认权限在跨包子类中的访问混淆
很多开发者误以为“子类能继承父类所有非 private 成员”,但实际能否访问取决于修饰符和包关系:
- default(不写修饰符):同包可见;跨包子类不能访问,哪怕继承了也不行
- protected:同包可见 + 跨包子类可见;但跨包普通类仍不可见
- private:子类完全不可见、不可访问,只能通过父类 public/protected 的 getter/setter 间接操作
典型坑点:在不同包的子类中直接访问父类 default 字段或方法,编译报错却误以为是继承失败。
多态下方法调用的“编译看左边,运行看右边”误区
向上转型后(如 Animal a = new Dog();),调用方法时:
立即学习“Java免费学习笔记(深入)”;
- 成员变量:访问的是编译类型(左边)的变量,不具有多态性
- 成员方法:执行的是运行类型(右边)重写后的方法,即动态绑定
- 静态方法:编译和运行都看左边,无多态,只是“隐藏”而非“重写”
容易踩坑的情形:
• 在父类方法中调用被子类重写的方法(如模板方法模式),但子类构造未完成,导致访问未初始化字段
• 用 instanceof 判断后向下转型,却忽略 instanceof null 安全性(null instanceof AnyClass 返回 false,不抛异常,但后续强转会 NPE)
抽象类实现规则与子类“父债子偿”的强制约束
抽象类不是语法糖,而是设计契约。关键约束如下:
- 含抽象方法的类必须声明为 abstract;抽象类可不含抽象方法,但不能被实例化
- 普通子类继承抽象类,必须实现所有未实现的抽象方法,否则自身也必须声明为 abstract
- 抽象方法不能是 private / final / static —— 因为它们与“强制子类覆盖”的语义冲突
- 抽象类可以有构造方法(用于初始化共用字段),但仅在子类构造时被调用,不创建抽象类对象
高频错误:
• 子类只重写部分抽象方法,忘记其余,编译报错却不知原因
• 在抽象类构造方法中调用抽象方法(子类尚未构造,JVM 允许但逻辑危险,常返回默认值)
• 把接口和抽象类混用,误以为 abstract class A extends B, C 可行(Java 不支持多继承)


















