【问题标题】:Why default (super) constructor is invoked instead of a blank constructor? [duplicate]为什么调用默认(超级)构造函数而不是空白构造函数? [复制]
【发布时间】:2016-06-22 13:53:51
【问题描述】:

在这个例子中,我有一个带有空白构造函数的子类。在超类中提供了两个构造函数。当我在下面的代码中执行 main 时,结果显示它打印“我是没有参数的超级构造函数”。 我的问题是,为什么编译器会忽略子类中的空白构造函数?如果我能接受这种“无知”,那么我理解编译器将执行子类的默认构造函数,在这种情况下,它是超类中没有参数的构造函数。 这是子类:

package extendisevil;

public class SubConstructorInherit extends ConstructorInherit {

  public SubConstructorInherit(String param) {

  }

  public static void main(String[] args) {

    SubConstructorInherit obj = new SubConstructorInherit("valami");

  }
}

这里是超级:

package extendisevil;

public class ConstructorInherit {

  public ConstructorInherit(String name) {
    System.out.println("I am the super constructor with String parameter: " + name);
  }

  public ConstructorInherit() {
    System.out.println("I am the super constructor without parameter.");
  }

}

感谢您的帮助!

【问题讨论】:

    标签: java inheritance constructor


    【解决方案1】:

    Java 没有忽略子类的构造函数,java 调用它。但是,java 还必须构造 every 超类,并且由于您没有在子类构造函数中调用特定的超构造函数,因此 java 只是默认为无参数构造函数。如果您想在父类中调用除无参数构造函数之外的任何其他构造函数,您可以通过调用 super(/* args */); 来实现,不过这必须是构造函数中的第一条语句:

    class Parent {
        Parent() {
            System.out.println("Parent()");
        }
        Parent(String name) {
            System.out.println("Parent(String): " + name);
        }
    }
    
    class Child extends Parent {
        Child() {
            //calls "super()" implicitly as we don't call a constructor of Parent ourselfs
            System.out.println("Child()");
        }
    
        Child(String name) {
            super(name); //we explicitly call a super-constructor
            System.out.println("Child(String): " + name);
        }
    }
    
    new Child();
    new Child("A Name");
    

    打印:

    Parent()
    Child()
    Parent(String): A Name
    Child(String): A Name
    

    如果一个类不提供无参数构造函数,而是提供带参数的构造函数,则子类构造函数必须显式调用给定构造函数之一。

    【讨论】:

    • 我在这里吹毛求疵,但在这种情况下我们真的不应该使用术语default constructor,更好的名称是no-arg constructor。原因是,default constructor 是在没有任何显式构造函数的情况下自动生成的无参数构造函数类的特定名称。
    • 你是对的,编辑它。
    • 也许隐式与显式的使用会使解释具体化。
    • 感谢您的帮助。我错过了java构造每个超类以及子类。再次感谢您的明确解释。
    【解决方案2】:

    超类具有相同类型的参数列表这一事实无关紧要 - 如果传递给子类的字符串与传递给超类的字符串具有完全不同的语义怎么办? (不清楚为什么nameparam 是同一个意思)

    如果您需要调用特定的非零参数构造函数,最好明确将参数传递给超级构造函数(以多敲几下键为代价),而不是错误地假设应该调用特定的 ctor。

    【讨论】:

      猜你喜欢
      • 2016-03-25
      • 2015-06-10
      • 2012-06-28
      • 1970-01-01
      • 2013-05-06
      • 1970-01-01
      • 1970-01-01
      • 2013-04-25
      相关资源
      最近更新 更多