当我创建一个抽象类时,然后是一个构造函数。 为什么在子类中构造一个具有相同参数的构造函数是必须的,我在我的超类中声明了这些参数?
答案 0 :(得分:1)
仅当您的抽象基类没有定义no-arg默认构造函数时。因为,您向抽象超类添加了参数化构造函数,编译器现在不会自动提供默认构造函数。
说
是不对的为什么在子类中使用我在超类中声明的相同参数构造一个构造函数是必须的?
因为你可以很好地定义像
这样的子类构造函数SubClass(/* no parameters */) {
super(1); // calls SuperClass(int i) constructor
}
答案 1 :(得分:0)
要知道的关键是子类中的构造函数必须在父类中调用构造函数。一种方法是添加该调用:
public MySubClass(int i) {
super(i);
... more code goes here ...
}
除非父类具有带有单个int参数的构造函数,否则不会编译。
如果你没有调用父构造函数,编译器会为你添加一个,并调用父类中的默认的no-arg构造函数。生成的代码看起来像这样:
public MySubClass(int i) {
super(); // Note: this line added by compiler if not present
... original code goes here ...
}
但是,同样,父类必须有一个无参数的构造函数。
如果没有无参数构造函数,很容易创建一个类,因为通常我们习惯于为编译器添加一个no-arg构造函数。这就是它调用默认构造函数的原因。
但是,如果父类具有带参数的构造函数,则不会创建默认构造函数,第二个代码示例将失败。 (实际上,无论是将调用放在父级,无参数构造函数还是依靠编译器添加它,都会失败。)
一种解决方案是将明确的无参数构造函数与带有参数的常规构造函数一起添加到父类。如果你想限制哪些类可以调用它,你甚至可以使它protected
。
另一种解决方案是在子类中将调用添加到实际存在的构造函数中。在该示例中,这将是采用int
的单参数构造函数。