我正在学习Java(二年级IT学生),我遇到了一些问题。继承要准确。这是代码:
class Bazowa
{
public Bazowa(int i)
{
System.out.println("konstruktor bazowy 1");
}
public Bazowa(int j, int k)
{
System.out.println("konstruktor bazowy 2");
}
}
class Pochodna extends Bazowa
{
/* Pochodna()
{
System.out.println("konstruktor pochodny bez parametru");
} */
Pochodna(int i)
{
super(i);
System.out.println("konstruktor pochodny z parametrem");
}
}
所以,Pochodna类扩展了Bazowa类,我的练习是创建一个只包含带参数的构造函数的超类和一个具有两种类型(有和没有)的子类。
当我评论Pochodna课程中的第一个构造函数时,一切正常,但我真的不知道如何在不评论该部分的情况下使其工作。我想我必须以某种方式从第一个调用构造函数,但不知道如何做到这一点。
任何帮助将不胜感激, 保罗
答案 0 :(得分:8)
Pochodna
的第一个构造函数默认调用super()
,这是Bazowa
中没有的构造函数。
你应该在Pochodna()
中调用一个带有1或2个参数的基础构造函数,或者在基类中创建一个没有参数的构造函数。
编辑:由于您说您正在学习Java,我将在答案中添加一些额外的解释。
每个类都必须有一个构造函数,所以当你没有显式声明一个时,编译器会为你这样做,创建一个没有参数的默认构造函数。如果您明确声明构造函数,则不会添加此构造函数。
在继承中,子类是父类的“特化”。这意味着子类包含父类的属性和行为,并在它们上进行扩展。但是你没有再次声明父元素(除非你真的想要覆盖东西)。因此,当您创建子实例时,必须以某种方式初始化从父项中获取的元素。为此,您拥有super(...)
构造。
在子构造函数中必须要做的第一件事就是调用super(...)
,以便在子项尝试对它们执行某些操作之前正确初始化从父项中获取的元素(您也可以调用另一个子构造函数this(...)
- 在这种情况下,调用链中的最后一个子构造函数将调用super(...)
)。
因此,编译器会再次向super()
添加一个默认调用 - 没有参数 - 当你不在孩子身上这样做的时候。
在Pochodna
的第一个构造函数中,由于您未自行调用super(i)
或super(j, k)
,因此默认情况下会调用super()
。但是在父类中,您显式指定了构造函数,因此默认值不是由编译器创建的。从这里异常,你最终调用一个不存在的构造函数。
希望这样可以更轻松地学习继承。欢呼声。
答案 1 :(得分:2)
您需要指定以下内容:
Pochodna()
{
super(0);
}
这里的技巧是,因为你为超类指定了一个构造函数,所以编译器不会为你创建一个no-arg构造函数。当你在超类中创建零arg构造函数时,它会尝试在子类中调用no-arg构造函数而无法找到任何内容。
简而言之,在构造函数中调用另一个构造函数(在超类或同一个类中)不是可选的。您可以显式指定另一个构造函数,也可以插入对超类'zero-arg构造函数的调用。
答案 2 :(得分:1)
由于基类没有无参数构造函数,因此需要使用super
显式调用构造函数,提供某种默认值。
例如:
Pochodna()
{
super(0);
System.out.println("konstruktor pochodny bez parametru");
}
或者,您可以在基类中创建protected
无参数构造函数。它不能从外部直接访问,但派生类将能够使用它。
答案 3 :(得分:1)
其他答案处理对超级构造函数的调用。
请注意,您也可以这样做:
Pochodna() {
this(0);
System.out.println("konstruktor pochodny bez parametru");
}
会将你的其他构造函数称为Pochodna。只是另一种选择。研究输出以了解正在发生的事情。
答案 4 :(得分:0)
由于父项中不存在默认构造函数,因此必须在子构造函数中调用其他构造函数:
Pochodna() {
super(10);
}