Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/349.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么要在构造函数中调用super()?_Java_Superclass - Fatal编程技术网

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();
        }
    }