Java 为什么要在构造函数中调用super()?
我正在处理一个扩展了Java 为什么要在构造函数中调用super()?,java,superclass,Java,Superclass,我正在处理一个扩展了JFrame的类 这不是我的代码,它在开始构建GUI之前调用super。我想知道为什么要这样做,因为我总是访问超类的方法,而不必调用super()当您自己不调用父类的空构造函数时,会自动调用父类的空构造函数super()。这就是为什么你从来不用在代码中这么做。这是为你做的 当您的超类没有无参数构造函数时,编译器将要求您使用适当的参数调用super。编译器将确保正确实例化该类。因此,这不是你必须担心太多的事情 无论是否在构造函数中调用super(),都不会影响调用父类方法的能力
JFrame
的类
这不是我的代码,它在开始构建GUI之前调用
super
。我想知道为什么要这样做,因为我总是访问超类的方法,而不必调用super()代码>当您自己不调用父类的空构造函数时,会自动调用父类的空构造函数super()
。这就是为什么你从来不用在代码中这么做。这是为你做的
当您的超类没有无参数构造函数时,编译器将要求您使用适当的参数调用super
。编译器将确保正确实例化该类。因此,这不是你必须担心太多的事情
无论是否在构造函数中调用super()
,都不会影响调用父类方法的能力
作为旁注,有人说为了清楚起见,通常最好手动进行调用。它只调用超类的默认构造函数。有一个对super()的隐式调用
对于所有具有父类(Java中的每个用户定义类)的类都没有参数,因此通常不需要显式调用它。但是,如果父级构造函数接受参数,并且希望指定参数,则可以使用带参数的super()
调用。此外,如果父级的构造函数采用参数,并且没有默认的无参数构造函数,则需要使用参数调用super()
例如,对super()
的显式调用为您提供了对框架标题的额外控制:
class MyFrame extends JFrame
{
public MyFrame() {
super("My Window Title");
...
}
}
我们可以使用super关键字访问超类成员
如果您的方法重写其超类的方法之一,则可以通过使用关键字super
来调用被重写的方法。您还可以使用super来引用隐藏字段(尽管不鼓励隐藏字段)。考虑这个类,超类:
public class Superclass {
public void printMethod() {
System.out.println("Printed in Superclass.");
}
}
//下面是一个名为subclass的子类,它重写printMethod()
:
在子类中,简单名称printMethod()
指的是在子类中声明的名称,它覆盖了超类中的名称。所以,要引用从超类继承的printMethod()
,子类必须使用限定名,使用super,如图所示。编译和执行子类将打印以下内容:
Printed in Superclass.
Printed in Subclass
我们可以使用super关键字访问超类元素
假设我们有两个类,父类和子类,具有不同的方法foo实现。现在在子类中,如果我们想调用父类的方法foo,我们可以通过super.foo()来实现;我们还可以通过super关键字访问父元素
class parent {
String str="I am parent";
//method of parent Class
public void foo() {
System.out.println("Hello World " + str);
}
}
class child extends parent {
String str="I am child";
// different foo implementation in child Class
public void foo() {
System.out.println("Hello World "+str);
}
// calling the foo method of parent class
public void parentClassFoo(){
super.foo();
}
// changing the value of str in parent class and calling the foo method of parent class
public void parentClassFooStr(){
super.str="parent string changed";
super.foo();
}
}
public class Main{
public static void main(String args[]) {
child obj = new child();
obj.foo();
obj.parentClassFoo();
obj.parentClassFooStr();
}
}
上述答案都不能回答“为什么”。找到了一个很好的解释:
子类可以有自己的私有数据成员,因此子类可以
也有自己的构造函数
子类的构造函数只能初始化实例
子类的变量。因此,当一个子类对象
实例化的子类对象也必须自动执行一个
超类的构造函数
干杯我们使用super关键字来调用超类的成员
由于子类从其父类继承所有成员(字段、方法、嵌套类),并且由于构造函数不是成员(它们不属于对象,它们负责创建对象),因此子类不会继承它们
因此,我们必须显式地调用父构造函数,以便在需要为超类创建对象时,构造函数链保持连接。在创建对象时,只能调用一个构造函数。通过super,我们可以在需要时从当前构造函数中调用另一个构造函数
如果您想知道为什么它存在于一个不扩展任何其他类的类中,那么请记住默认情况下每个类都遵循对象类。因此,在构造函数中保持super是一个很好的实践
注意:即使第一条语句中没有super(),编译器也会为您添加它 旁注:扩展JFrame
可能不是您想要做的。扩展意味着一种is-a关系。除非您正在制作一个新的窗口组件,否则您可能应该扩展JComponent
。但没有回答“为什么”这个问题。不要对非代码文本使用代码格式。第一句话不正确,所有这些都不能回答问题。同样重要的是:调用超类构造函数必须是子类构造函数的第一行。相关信息请点击这里:@Eugene-Yes。这也在Oracle的官方Java教程中提到。
class parent {
String str="I am parent";
//method of parent Class
public void foo() {
System.out.println("Hello World " + str);
}
}
class child extends parent {
String str="I am child";
// different foo implementation in child Class
public void foo() {
System.out.println("Hello World "+str);
}
// calling the foo method of parent class
public void parentClassFoo(){
super.foo();
}
// changing the value of str in parent class and calling the foo method of parent class
public void parentClassFooStr(){
super.str="parent string changed";
super.foo();
}
}
public class Main{
public static void main(String args[]) {
child obj = new child();
obj.foo();
obj.parentClassFoo();
obj.parentClassFooStr();
}
}