抽象类可定义构造方法但不能直接实例化,其构造方法仅在子类创建对象时由子类构造器调用;默认为protected,禁止private;若定义了带参构造器则无默认无参构造器;子类必须显式调用super()且位于首行。

抽象类可以定义构造方法,但不能直接实例化,它的构造方法只在子类创建对象时被调用(由子类构造器隐式或显式触发)。
抽象类的构造方法必须存在且可访问
抽象类的构造方法默认是 package-private(包内可见),但通常建议声明为 protected,确保子类能调用它。Java 不允许抽象类有 private 构造方法(除非你明确禁止继承,但这与抽象类设计初衷矛盾)。
- 抽象类不写构造方法时,编译器会提供一个无参、protected 的默认构造器
- 只要写了任意构造方法(哪怕带参数),就不会再生成默认无参构造器
- 子类构造器第一行若没显式调用
super(...),就会尝试调用父类无参构造器;若父类没有无参构造器,编译失败
子类必须正确调用抽象父类的构造方法
子类构造器中,必须通过 super(...) 显式调用父类构造方法(可以是带参或无参),且该调用必须是第一句。这是 Java 构造链的强制要求。
- 如果抽象类只有带参构造器,子类构造器就必须显式写
super(参数) - 如果抽象类提供了无参构造器(显式或默认),子类可省略
super()(编译器自动插入) - 子类也可在自己构造器中做初始化逻辑,再委托给父类构造器
典型写法示例
以下是一个常见模式:
abstract class Animal {
protected String name;
protected int age;
// 带参构造器(推荐显式声明 protected)
protected Animal(String name, int age) {
this.name = name;
this.age = age;
}
// 可选:再提供一个无参构造器,方便子类简化调用
protected Animal() {
this("unknown", 0);
}
public abstract void makeSound();
}
class Dog extends Animal {
private String breed;
// 必须调用父类构造器
public Dog(String name, int age, String breed) {
super(name, age); // 显式调用抽象父类构造器
this.breed = breed;
}
@Override
public void makeSound() {
System.out.println(name + " barks");
}
}
注意事项
抽象类构造方法中不能调用 抽象方法(因为子类对象尚未完成初始化,会导致行为未定义)。JVM 允许语法上这么写,但运行时可能得到 null 或默认值,极易引发 bug。
- 避免在抽象类构造器中调用
this.xxx(),如果xxx()是抽象方法 - 构造器适合做字段初始化、参数校验、资源预分配等与继承结构无关的通用准备
- 抽象类构造器执行时机:在子类构造器体执行前,属于对象创建过程中的“父类初始化阶段”
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











