Java 继承中的构造方法调用规则详解

前言

最近在学习 Java 继承时,对构造方法的调用规则产生了一些疑问:如果父类没有无参构造会怎样?多级继承时要怎么处理?子类自身构造方法又会如何影响调用链?通过一番研究和实验,我整理了这篇笔记,分享给大家,希望能帮助到有同样困惑的小伙伴。

一、基本规则:构造方法的调用顺序

在 Java 中,当我们通过 new 创建一个对象时,构造方法的调用遵循以下规则:

  1. 从父类到子类:构造方法会从最顶层的父类开始,逐级向下调用,直到子类本身。
  2. 默认调用无参构造:如果子类构造方法没有明确指定调用父类的某个构造方法(即没有写 super(...)),Java 会自动调用父类的无参构造方法 super()

但实际情况会因为父类和子类的构造方法定义而有所不同,下面我们逐步分析。

二、父类没有无参构造怎么办?

情况描述

如果父类只定义了有参构造方法,没有无参构造方法,而子类构造方法没有手动调用父类的有参构造,会发生什么?

结论

会报错!

子类构造方法默认会调用 super(),但如果父类没有无参构造,编译器会提示错误,比如:“没有默认构造方法”。
解决办法:子类必须用 super(参数) 手动调用父类的有参构造。

代码示例
class A {
    public A(int x) { // 只有有参构造
        System.out.println("A 的有参构造: " + x);
    }
}

class B extends A {
    public B() {
        super(10); // 必须手动调用
        System.out.println("B 的构造");
    }
}

public class Main {
    public static void main(String[] args) {
        B b = new B();
    }
}
输出
A 的有参构造: 10
B 的构造

三、多级继承时构造方法如何调用?

疑问

如果有多个父类(继承链),每个父类都没有无参构造,需要在子类中写多个 super 调用吗?

澄清

Java 是单继承,一个类只能直接继承一个父类,所以不存在 “多个父类” 的情况。

但如果是多级继承(比如 A ← B ← C),需要沿着继承链逐级处理构造方法。

结论

每个子类只需关心自己的直接父类,用 super(参数) 调用即可。

调用顺序依然是从最顶层父类开始,逐级向下。

代码示例

class A {
    public A(int x) {
        System.out.println("A 的构造: " + x);
    }
}

class B extends A {
    public B(int x) {
        super(x);
        System.out.println("B 的构造");
    }
}

class C extends B {
    public C(int x) {
        super(x);
        System.out.println("C 的构造");
    }
}

public class Main {
    public static void main(String[] args) {
        C c = new C(5);
    }
}
输出
A 的构造: 5
B 的构造
C 的构造

四、父类有无参构造时的调用规则

情况描述

如果继承链上的每个类都有无参构造,创建子类对象时会发生什么?

结论

Java 会自动调用每个类的无参构造,从最顶层父类到子类。

调用次数 = 继承链上的类总数(包括子类本身)。

代码示例

class A {
    public A() {
        System.out.println("A 的无参构造");
    }
}

class B extends A {
    public B() {
        // 自动调用 super()
        System.out.println("B 的无参构造");
    }
}

class C extends B {
    public C() {
        // 自动调用 super()
        System.out.println("C 的无参构造");
    }
}

public class Main {
    public static void main(String[] args) {
        C c = new C();
    }
}
输出
A 的无参构造
B 的无参构造
C 的无参构造

五、子类没有无参构造会怎样?

情况描述

如果子类只定义了有参构造,没有无参构造,会影响构造链吗?

结论

子类没有无参构造时,必须用有参方式创建对象(比如 new C(10))。

但构造链依然会从父类开始,父类的构造方法(无参或有参)依然会被调用。

代码示例

class A {
    public A() {
        System.out.println("A 的无参构造");
    }
}

class B extends A {
    public B() {
        // 自动调用 super()
        System.out.println("B 的无参构造");
    }
}

class C extends B {
    public C(int x) { // 只有有参构造
        // 自动调用 super()
        System.out.println("C 的有参构造: " + x);
    }
}

public class Main {
    public static void main(String[] args) {
        C c = new C(10);
    }
}
输出
A 的无参构造
B 的无参构造
C 的有参构造: 10

    六、主动调用有参构造的影响

    问题

    用 super 主动调用父类的有参构造方法,会不会再调用无参构造方法?

    答案

    不会。只要子类显式调用了 super(参数),编译器就不会再自动调用父类的无参构造方法。父类的构造方法在一次对象创建中只会被调用一次。

    示例
    class Parent {
        public Parent() {
            System.out.println("父类无参构造");
        }
        public Parent(String s) {
            System.out.println("父类有参构造: " + s);
        }
    }
    
    class Child extends Parent {
        public Child() {
            super("Test"); // 显式调用有参构造
            System.out.println("子类构造");
        }
    }
    
    public class Main {
        public static void main(String[] args) {
            Child child = new Child();
        }
    }
    输出
    父类有参构造: Test
    子类构造

    七、总结:构造方法调用规则

    • 默认行为:子类构造方法会自动调用父类的无参构造(super())。
    • 无参构造缺失:如果父类没有无参构造,子类必须用 super(参数) 手动调用,否则报错。
    • 多级继承:构造方法从顶层父类逐级调用到子类,每个类只需关心自己的直接父类。
    • 全无参构造:自动调用所有类的无参构造,顺序是父类到子类。
    • 子类有参构造:不影响构造链,但创建对象时必须传参。
    • 主动调用有参构造的影响:当子类显式使用 super(参数) 调用父类的有参构造方法时,编译器不会再自动调用父类的无参构造方法。在一次对象创建过程中,父类的构造方法仅会被调用一次。

    你可能感兴趣的:(JAVA,java,开发语言)