用Java中的构造函数继承

时间:2017-05-23 12:05:19

标签: java inheritance constructor

请告诉我以下代码中的问题?

class boxdemo1 {
    public static void main(String args[]) {
        boxweight weightbox = new boxweight(2, 3, 5, 4);
        System.out.println(weightbox.volume());
    }
}

class boxinfo {
    int l, b, h;

    /*
     * boxinfo() { l=b=h=-1; }
     */
    boxinfo(int a, int b, int c) {
        l = a;
        this.b = b;
        h = c;
    }

    int volume() {
        return l * b * h;
    }
}

class boxweight extends boxinfo {
    int w;

    boxweight(int a, int b, int c, int w) {
        l = a;
        this.b = b;
        h = c;
        this.w = w;
    }
}

编译时,显示以下错误: “类boxinfo中的构造函数boxinfo不能应用于给定类型; 需要:INT,INT,INT;发现:没有争论;实际和正式的参数列表的长度不同。“

但是当我编译它包括被注释的代码(即boxinfo()构造函数)时,它会被编译。为什么需要包含默认构造函数?

6 个答案:

答案 0 :(得分:1)

由于这是构建实例的超类部分以使某些工作正常所必需的,因此需要调用超级构造函数。

如果在构造函数的第一个语句中没有调用super()的语句(或this()最终会得到super()),编译器将添加对{{{ 3}}(super();)。

由于您没有没有参数的构造函数,因此无法编译,因为没有与此语句匹配的构造函数。

同样,如果一个类没有定义任何构造函数,那么default constructor就像

一样实现
public MyClass(){ super(); }

如果MyClass的超类仅提供带有default constructor

中所述参数的构造函数,则会产生同样的问题
  

如果默认构造函数是隐式声明但超类没有可访问的构造函数(第6.6节),它不带参数且没有throws子句,那么这是一个编译时错误。

要纠正您的问题,只需调用正确的超级构造函数或定义不带参数的构造函数(不再称为默认构造函数,只有编译器定义的构造函数是默认构造函数;)

答案 1 :(得分:1)

  

错误原因 -

     

子类构造函数调用父类的构造函数   需要四个参数。

     

boxinfo类中没有构造函数需要四个   参数。

此外,

Java编译器自动将super()构造函数插入到子类中。这个超级构造函数的含义是去并执行父类中不带参数的构造函数

根据你的计划:

boxinfo(int a, int b, int c) {
        l = a;
        this.b = b;
        h = c;
    }

运行程序时,编译器会删除默认构造函数,因为父类中的构造函数需要三个参数。

如果没有为boxweight类添加构造函数,Java编译器会自动插入默认构造函数。由于您已经添加了四个参数,编译器将检查四个参数构造函数。正如我前面所说的那样extends构造函数中的另一个类(boxinfo),Java编译器也会自动在构造函数的第一行插入super()

它看起来像这样:

class boxweight extends boxinfo{
   boxweight (int a, int b, int c, int w){
     super();
     //.....
   }
}

我们可以将super()添加到子类的构造函数中,使其与父类中的现有构造函数匹配。

解决你的问题,

在子类的构造函数(第一行)中添加super(),并添加值以匹配父类构造函数。

像这样:

boxweight(int a, int b, int c, int w) {
   super(a, b, c);
   this.w = w;
}

现在您不需要这些分配l = a;this.b = b;h = c;,因为通过构造函数将其发送到父类。

注意:添加super()时必须是子类构造函数中的第一行。

答案 2 :(得分:0)

通过设置boxinfo(int a, int b, int c)构造函数,java boxinfo设置的默认无参数构造函数将被删除。然后,当您调用boxweight(int a,int b,int c,int w)构造函数时,由于boxweight类继承自boxinfo,因此您隐式调用boxinfo中的默认构造函数,该构造函数刚被覆盖。

要避免这种情况,请在boxinfo中创建一个无参数构造函数,或在super(a, b, c)中明确调用boxweight

答案 3 :(得分:0)

当您重载默认构造函数时,这是必要的,默认构造函数不再存在。

例如:

class boxweight extends boxinfo {
     boxweight(int a, int b, int c, int w) {
         ...
     }
}

实际上与:

相同
class boxweight extends boxinfo {
     boxweight(int a, int b, int c, int w) {
         super();
         ...
     }
}

但是在boxinfo这样的构造函数不再存在,你创建了一个自定义构造函数。您需要将其保存在代码中以使其可调用。

答案 4 :(得分:0)

子类构造函数必须通过调用其超类的至少一个构造函数来初始化它的超类成员。

如果超类没有默认构造函数(如示例中的默认构造函数),则必须执行此操作。

在这种情况下,您的boxweight构造函数必须初始化boxinfo声明的其他成员。因此,您必须调用super(...)来初始化boxinfo

因此,您的boxweight构造函数将变为:

boxweight(int a, int b, int c, int w) {
    super(a,b,c); // put this call here and remove other lines.
    this.w = w; // this is sufficient
}

PS:我建议您遵循命名约定来命名您的类,方法和其他Java工件。

http://www.oracle.com/technetwork/java/codeconventions-135099.html

答案 5 :(得分:-2)

当你使用继承扩展一个类并创建子类的对象时,子类的构造函数将调用它的父类构造函数。在你的情况下,你使用下面的构造函数它将调用默认的构造函数。在你的类中你没有指定默认的构造函数在这种情况下,您可以使用super来调用父类中声明的构造函数。

boxweight(int a, int b, int c, int w) {
       super(a, b, c); //or declared default constructor
        l = a;
        this.b = b;
        h = c;
        this.w = w;
    }