抽象类可定义构造方法初始化子类共有字段,子类创建对象时隐式或显式调用;需设字段为protected、构造方法非private;无参构造或初始化块适合默认值;final字段须在构造中赋值;避免构造中调用抽象方法。

抽象类可以定义构造方法,用于初始化所有子类共有的属性字段。虽然不能直接实例化抽象类,但子类在创建对象时,会隐式或显式调用父类(抽象类)的构造方法,从而完成公共字段的初始化。
抽象类中定义带参构造方法
在抽象类中声明字段,并提供带参数的构造方法,让子类在初始化时传入必要值:
- 字段通常设为 protected,方便子类访问
- 构造方法不能是 private,否则子类无法调用
- 若未定义无参构造方法,子类构造器必须显式调用 super(...)
示例:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
abstract class Animal {
protected String name;
protected int age;
// 带参构造方法,初始化共有字段
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
}
class Dog extends Animal {
// 必须调用父类构造方法
public Dog(String name, int age) {
super(name, age); // 初始化 name 和 age
}
}
抽象类中使用无参构造 + 初始化块(适合固定默认值)
如果公共字段有统一默认值,可用无参构造方法或实例初始化块:
立即学习“Java免费学习笔记(深入)”;
- 无参构造中设置默认值,子类可不传参(前提是父类提供了无参构造)
- 实例初始化块会在每次构造时执行,适用于简单赋值逻辑
示例:
abstract class Vehicle {
protected String brand = "Unknown";
protected int wheels = 4;
// 无参构造(可选)
public Vehicle() {}
// 或配合初始化块(效果类似)
{
System.out.println("Vehicle common init");
}
}
class Car extends Vehicle {
public Car() {
// 自动调用 Vehicle(),brand 和 wheels 已初始化
}
}
结合 final 字段确保不可变性
若某些公共字段一旦设定就不应改变(如 ID、类型标识),可声明为 final,并在构造方法中强制初始化:
- final 字段只能在声明时、初始化块或构造方法中赋值
- 抽象类的 final 字段需由子类通过 super() 提供值
示例:
abstract class Product {
protected final String code;
protected String description;
public Product(String code, String description) {
this.code = code; // final 字段必须在此赋值
this.description = description;
}
}
class Book extends Product {
public Book(String code, String description) {
super(code, description); // 必须传递 code
}
}
避免在抽象类构造中调用抽象方法
构造过程中调用子类重写的方法可能导致未预期行为(子类字段尚未初始化):
- JVM 先调用父类构造,再初始化子类字段
- 若抽象构造中调用 abstract method,实际执行的是子类实现——但此时子类字段可能为 null 或默认值
- 应尽量避免,或确保该方法不依赖子类未初始化的状态
不推荐写法:
abstract class Base {
protected String data;
public Base() {
init(); // ❌ 可能引发空指针或逻辑错误
}
abstract void init();
}
不复杂但容易忽略:抽象类的构造方法本质和普通类一样,只是它不服务于直接实例化,而是为继承链提供统一初始化入口。关键在于明确字段归属、控制访问权限、配合子类构造协同工作。

















