【问题标题】:Which super constructor will be called? And is super constructor still invoked if i don't invoke a super constructor in subclass?将调用哪个超级构造函数?如果我不在子类中调用超级构造函数,是否仍然调用超级构造函数?
【发布时间】:2015-12-07 15:11:06
【问题描述】:
public class Faculty extends Employee {
    public static void main(String[] args) {
        new Faculty();
    }

    public Faculty() {
        super(“faculty”);
    }
}

class Employee extends Person {
     private String name;
     public Employee() {
     name = “no name”;
     System.out.println("(3) Employee's no-arg constructor is invoked");
     }

     public Employee(String s) {
     name = s;
     System.out.println(s);
     }
}

class Person {
    //What if there was a parameterized constructor here
    // e.g. public Person(String s){
    //            ... code ...
    //      }
}

在上面的 Java 代码中,如果我将 Person 类留空,并在 Faculty 类的无参数构造函数中调用超级构造函数,则会调用 Employee 的构造函数。但是如果 Person 类中有一个参数化的构造函数怎么办。哪个超级构造函数会被调用?员工一号还是个人一号?

如果我不在子类中调用超级构造函数,是否仍会调用超级构造函数?

【问题讨论】:

  • 为什么不试试呢?

标签: java oop inheritance constructor super


【解决方案1】:

如果您向Person 添加参数化构造函数,您的Employee 类将无法编译,因为默认的无参数构造函数将不再隐含,但您的Employee 构造函数将需要调用它。

现在,如果您的 Person 类同时具有无参数和 String-parametrized 构造函数(具有相同的 Employee 实现),您的代码将编译,并且调用 Employee 的构造函数仍然会首先调用Person 的无参数构造函数。

【讨论】:

    【解决方案2】:

    但是如果 Person 类中有一个参数化的构造函数呢?

    如果你这样做,你会得到一个很好的编译错误。

    如果你的超类构造函数有参数,你的子类将调用super(arguments),其中参数与参数匹配。

    如果超类构造函数没有任何参数,您的子类将隐式调用super()。因此我们不必再次显式调用super()

    示例:

    class GrandParent
    {
        public GrandParent(String s){
            System.out.println("Calling my grandpa");
        }
    }
    
    class Parent extends GrandParent
    {
        public Parent(){
            super("");
            System.out.println("Calling my pa");
        }   
    }
    
    class Child extends Parent
    {
        public Child(){
            //super() implicitly invoked
            System.out.println("Calling my child"); 
        }
    }
    

    运行以下命令时:

    class Test
    {
        public static void main(String[] args){
            new Child();
        }
    }
    

    你得到:

    Calling my grandpa
    Calling my pa
    Calling my child
    

    以上输出回答了您后续的问题:

    员工一号还是个人一号? 如果我不在子类中调用超级构造函数,是否仍然调用超级构造函数?

    【讨论】:

    • 不需要在每个构造函数上都有String 参数。您只需要一个实际参数来匹配形式参数。例如,Child 构造函数可以是无参数的,并以 super("I am a Child"); 开头
    • @PatriciaShanahan 你说得对,谢谢提醒。我编辑了它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-23
    • 2016-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-29
    相关资源
    最近更新 更多