子类是否需要构造函数?

时间:2014-03-18 04:21:15

标签: java subclass superclass

我一直在学习继承,我只是好奇。我知道即使你不使用super()运算符,子类也会自动调用超类的构造函数,所以我想知道子类是否有必要使用构造函数它

4 个答案:

答案 0 :(得分:14)

如果超类没有默认构造函数(或者具有子类无法访问的构造函数),则子类需要构造函数。如果子类根本没有构造函数,编译器将自动创建一个public构造函数,它只是调用超类的默认构造函数。

关于调用super():每个构造函数必须做的第一件事是通过调用this()(可能带有一些参数)调用同一个类中的不同构造函数,或者通过调用调用其超类的构造函数super()(再次,可能有参数)。这些电话都不能去其他任何地方。如果构造函数不以任何一个开头,编译器将自动插入对super()的调用(不带任何参数)。因此,如果您想要的行为是调用默认的超类构造函数(并且很多时候都是这样),那么您不需要自己明确地调用super()

即使超类没有默认构造函数,也有一种情况是你不需要提供构造函数(事实上,你不能提供构造函数)。这种情况(在section 15.9.5.1 of the Java Language Sepcification中描述)是使用非默认构造函数创建类的匿名子类时;编译器将自动创建具有正确参数的构造函数,并调用相应的(非默认)超类构造函数。例如:

class X {
    public X(int value) { ... } // no default constructor!
    public void foo() { ... }
}

X myX = new X(3) {
    @Override
    public void foo() { ... }
};

然后myX将是X的匿名子类的实例,其中包含编译器生成的构造函数,该构造函数接受int参数并调用super(intArg)

因为无法为匿名类编写构造函数,所以会出现问题:如果在创建对象时需要进行一些对象初始化,该怎么办?解决方案是使用instance initializer block。例如:

X myX = new X(3) {
    // Field unique to this subclass of X:
    private int baz;
    {
        // code here runs as if it were at the start of every constructor
        baz = ...;
    }
    @Override
    public void foo() { ... }
};

答案 1 :(得分:2)

如果通过super()访问的默认超类构造函数可用,则子类不需要具有显式构造函数;它将自动获得默认的无参数构造函数。如果超类具有显式构造函数,所有构造函数都接受参数,那么子类也需要一个显式构造函数,因为如果没有这样的构造函数,就无法知道应该调用超类构造函数的参数。

答案 2 :(得分:2)

如果超类没有默认(即没有args)构造函数,那么必须定义一个调用特定超级构造函数的构造函数。

如果超类 有默认构造函数,则不必声明构造函数,因为如果你没有为你定义隐式的构造函数不要声明任何构造函数:

SubClass() {
    super();  // Note: the no-args super constructor may itself be implicit
}

因此,在这种情况下,您不必在子类中声明构造函数。

答案 3 :(得分:0)

如果默认构造函数在超类中可用,则编译器将在子类的默认构造函数中包含默认构造函数调用。例如 -

class  Base(){
  Base(){ // default constructor
    ...
  }
}

class Sub extends Base{
   // no constructor
}

在这种情况下不需要。

class  Base(){
  Base( int i){ // no default constructor
    ...
  }
}

class Sub extends Base{
   // no constructor
}

在这种情况下需要它。

class Sub extends Base{
   Sub(){ 
      Base(1);
   }
}