【问题标题】:Java inheritance - constructorsJava 继承 - 构造函数
【发布时间】:2011-09-09 01:55:34
【问题描述】:

在准备期末考试时,我在我目前正在学习的书中看到了以下陈述。考虑以下代码:

class A {
    public A(int x) {   }
}

class B extends A {
    public B(int x ) {   }
}

B类的构造函数中是否必须调用A类的构造函数(super(x))。该书指出这不是强制性的,因为它们具有确切的参数数量和类型。但是当我在 java 编译器中尝试这个时,会抛出以下错误:

A 类中的构造函数 A 不能 适用于给定类型;必需的: int 找到:没有参数原因: 实际和形式参数列表 长度不同

【问题讨论】:

    标签: java inheritance constructor


    【解决方案1】:

    编译器会自动在开头插入super()。

    然而,即使是构造函数参数,super()(不带参数)也被添加,它调用超类的 default 构造函数。而你没有,因此出现错误。

    你必须指定super(x)(调用A(x)),或者定义一个无参数的构造函数。

    顺便说一句,Eclipse 编译器给出了更好的错误信息:

    隐式超级构造函数 A() 未定义。必须显式调用另一个构造函数

    【讨论】:

    • 在这一行抛出错误:“public B(int x) {}”。我在问题中发布的代码是我要编译的所有代码(只是类定义,根本没有实例化)。
    • 它只会插入super()。它不会插入super(int)。因此这里的错误。在这种情况下,他确实需要致电super(x)。见download.oracle.com/javase/tutorial/java/IandI/super.html。
    【解决方案2】:

    当您没有默认构造函数并且您正在使用默认构造函数创建实例时会发生这种情况。因为如果您有任何参数化构造函数,那么编译器不会为您插入默认构造函数,而是您必须定义。

    【讨论】:

      【解决方案3】:

      编译器似乎尝试使用 super() 创建对超类默认构造函数的调用,但这是不可用的:

      required: int
      found:    no arguments
      

      但回到你的书:如果实际构造函数与直接超类中的构造函数具有完全相同的参数列表,我从未听说过可以跳过构造函数中的super 语句的规则。仅隐式添加了对超类默认构造函数的调用 (super()),但这要求超类具有默认构造函数。

      与您书中所写的内容(或与您对书面文本的理解相反)相反,这是语言规范中的一句话:

      如果构造函数体不是以显式构造函数调用开始 并且被声明的构造函数不是原始类 Object 的一部分,那么 编译器隐式假定构造函数体以 super 开头 类构造函数调用“super();”,调用它的构造函数 不带参数的直接超类。

      【讨论】:

        【解决方案4】:

        如果您有一个具有默认构造函数(无参数构造函数)的基类,则在扩展B 时,您无需显式调用super(),因为它以任何方式调用。

        但是当你有一个带参数的构造器时,在B中制作带参数的构造器时,你需要在super()中传入A的参数

        例子:

        class A {
            public A(int x) {   }
          }
        
          class B extends A {
            public B(int x ) 
            {
               super(x); // need to specify the parameter for class A
               //... 
            }
          }
        

        【讨论】:

          【解决方案5】:

          Java 需要调用超类的构造函数。因此,每当你生成子类的构造函数时,超类的构造函数都是IDE自己创建的。

          这是因为每当基类构造函数需要参数时,编译器认为它们将由基类构造函数填充。如果是默认构造函数,则可以。无需在子类中调用 super()。

          【讨论】:

            猜你喜欢
            • 2013-03-21
            • 2010-12-11
            • 1970-01-01
            • 2020-08-07
            • 1970-01-01
            • 2018-10-30
            • 1970-01-01
            • 1970-01-01
            • 2023-04-04
            相关资源
            最近更新 更多