抽象类会有构造函数吗

返回 面试

有。 抽象类可以定义构造器,只是不能 new 抽象类本身;子类实例化时会通过 super(...) 间接调用抽象类构造器,用于初始化父类共享字段。

与接口对比见 接口与抽象类


结论速记

类型能否有构造器能否直接 new构造器谁调用
普通类自己或外部
抽象类不能子类 super(...)
接口不能(无实例)不能

为什么抽象类需要构造器

抽象类常承载子类共享的状态(字段),这些字段需要在对象创建时初始化:

public abstract class Animal {
    protected String name;
 
    // 抽象类构造器:子类必须通过 super 调用
    public Animal(String name) {
        this.name = name;
    }
 
    public abstract void speak();
}
 
public class Dog extends Animal {
    public Dog(String name) {
        super(name);  // 调用抽象类构造器
    }
 
    @Override
    public void speak() {
        System.out.println(name + ": 汪汪");
    }
}
 
// new Animal("x");     // 编译错误:抽象类不能实例化
Animal d = new Dog("旺财"); // OK:实际创建的是 Dog,构造链完整

执行顺序new Dog("旺财")Dog 构造器 → super(name)Animal 构造器 → 初始化 name → 回到 Dog 构造器体 → 对象就绪。


常见追问

不写构造器会怎样?

与普能类一样:编译器自动生成无参默认构造器。若抽象类只写了有参构造器、未写无参构造器,子类必须显式 super(参数),否则编译报错。

public abstract class Base {
    public Base(int id) { /* ... */ }
}
 
public class Sub extends Base {
    public Sub() {
        super(1); // 必须,因为 Base 没有无参构造器
    }
}

抽象类构造器可以是 private 吗?

可以(语法合法),但会限制只有同文件内的静态内部子类等能访问;公开继承体系里几乎不用。工具类更常用 final class + private 构造器,而非抽象类。

抽象类构造器里能调抽象方法吗?

技术上可以编译,但不推荐:构造器执行时子类尚未初始化完成,若抽象方法已在子类实现,可能读到子类字段的默认值(尚未赋值),行为难料。实践上构造器只做字段赋值,不调多态方法。

和接口的区别(面试对比)

抽象类和接口的区别接口能有构造方法吗

对比抽象类接口
构造器
实例字段可有只有 public static final 常量
目的共享状态 + 部分实现定义能力契约

相关笔记