简体   繁体   English

为什么在构造函数中调用 super()?

[英]Why call super() in a constructor?

I'm dealing with a class which extends JFrame .我正在处理一个扩展 JFrame 的JFrame

It's not my code and it makes a call to super before it begins constructing the GUI.这不是我的代码,它在开始构建 GUI 之前调用了super I'm wondering why this is done since I've always just accessed the methods of the superclass without having to call super();我想知道为什么要这样做,因为我一直只是访问超类的方法而不必调用super();

There is an implicit call to super() with no arguments for all classes that have a parent - which is every user defined class in Java - so calling it explicitly is usually not required.有一个对super()的隐式调用,所有具有父类的类都没有参数 - 这是 Java 中每个用户定义的类 - 因此通常不需要显式调用它。 However, you may use the call to super() with arguments if the parent's constructor takes parameters, and you wish to specify them.但是,如果父构造函数接受参数,并且您希望指定它们,则可以使用带参数调用super() Moreover, if the parent's constructor takes parameters, and it has no default parameter-less constructor, you will need to call super() with argument(s).此外,如果父的构造函数接受参数,并且它没有默认的无参数构造函数,您将需要使用参数调用super() ) 。

An example, where the explicit call to super() gives you some extra control over the title of the frame:一个示例,其中对super()的显式调用为您提供了对框架标题的一些额外控制:

class MyFrame extends JFrame
{
    public MyFrame() {
        super("My Window Title");
        ...
    }
}

A call to your parent class's empty constructor super() is done automatically when you don't do it yourself.当您不自己调用时,会自动调用父类的空构造函数super() That's the reason you've never had to do it in your code.这就是您不必在代码中执行此操作的原因。 It was done for you.它是为你完成的。

When your superclass doesn't have a no-arg constructor, the compiler will require you to call super with the appropriate arguments.当您的超类没有无参数构造函数时,编译器将要求您使用适当的参数调用super The compiler will make sure that you instantiate the class correctly.编译器将确保您正确实例化该类。 So this is not something you have to worry about too much.所以这不是你需要担心的太多。

Whether you call super() in your constructor or not, it doesn't affect your ability to call the methods of your parent class.无论您是否在构造函数中调用super() ,它都不会影响您调用父类方法的能力。

As a side note, some say that it's generally best to make that call manually for reasons of clarity.作为旁注,有些人说为了清楚起见,通常最好手动进行调用。

We can access super class elements by using super keyword我们可以使用 super 关键字访问超类元素

Consider we have two classes, Parent class and Child class, with different implementations of method foo.考虑我们有两个类,Parent 类和 Child 类,它们具有不同的 foo 方法实现。 Now in child class if we want to call the method foo of parent class, we can do so by super.foo();现在在子类中如果我们想调用父类的foo方法,可以通过super.foo(); we can also access parent elements by super keyword.我们还可以通过 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();
        }
    }

它只是调用超类的默认构造函数。

We use super keyword to call the members of the Superclass.我们使用 super 关键字来调用超类的成员。

As a subclass inherits all the members (fields, methods, nested classes) from its parent and since Constructors are NOT members (They don't belong to objects. They are responsible for creating objects), they are NOT inherited by subclasses.由于子类从其父类继承了所有成员(字段、方法、嵌套类),并且由于构造函数不是成员(它们不属于对象。它们负责创建对象),因此它们不会被子类继承。

So we have to explicitly give the call for parent constructor so that the chain of constructor remains connected if we need to create an object for the superclass.因此,如果我们需要为超类创建对象,我们必须显式调用父构造函数,以便构造函数链保持连接。 At the time of object creation, only one constructor can be called.在创建对象时,只能调用一个构造函数。 Through super, we can call the other constructor from within the current constructor when needed.通过 super,我们可以在需要时从当前构造函数中调用另一个构造函数。

If you are thinking why it's there for a class that is not extending any other class, then just remember every class follows object class by default.如果您在想为什么它存在于不扩展任何其他类的类中,那么请记住默认情况下每个类都遵循对象类。 So it's a good practice to keep super in your constructor.所以在你的构造函数中保留 super 是一个很好的做法。

Note: Even if you don't have super() in your first statement, the compiler will add it for you!注意:即使您的第一条语句中没有 super(),编译器也会为您添加它!

We can Access SuperClass members using super keyword我们可以使用 super 关键字访问 SuperClass 成员

If your method overrides one of its superclass's methods, you can invoke the overridden method through the use of the keyword super .如果您的方法覆盖了其超类的方法之一,您可以通过使用关键字super调用被覆盖的方法。 You can also use super to refer to a hidden field (although hiding fields is discouraged).您还可以使用 super 来引用隐藏字段(尽管不鼓励隐藏字段)。 Consider this class, Superclass:考虑这个类,超类:

public class Superclass {

    public void printMethod() {
        System.out.println("Printed in Superclass.");
    }
}

// Here is a subclass, called Subclass, that overrides printMethod() : // 这是一个子类,称为 Subclass,它覆盖了printMethod()

public class Subclass extends Superclass {

    // overrides printMethod in Superclass
    public void printMethod() {
        super.printMethod();
        System.out.println("Printed in Subclass");
    }
    public static void main(String[] args) {
        Subclass s = new Subclass();
        s.printMethod();    
    }
}

Within Subclass, the simple name printMethod() refers to the one declared in Subclass, which overrides the one in Superclass.在子类中,简单名称printMethod()指的是在子类中声明的方法,它覆盖了超类中的方法。 So, to refer to printMethod() inherited from Superclass, Subclass must use a qualified name, using super as shown.因此,要引用从 Superclass 继承的printMethod() ,Subclass 必须使用限定名称,如图所示使用 super。 Compiling and executing Subclass prints the following:编译和执行子类打印以下内容:

Printed in Superclass.
Printed in Subclass

None of the above answers answer the 'why'.以上答案都没有回答“为什么”。 Found a good explanation here : 在这里找到了一个很好的解释:

A subclass can have its own private data members, so a subclass can also have its own constructors.子类可以有自己的私有数据成员,所以子类也可以有自己的构造函数。

The constructors of the subclass can initialize only the instance variables of the subclass.子类的构造函数只能初始化子类的实例变量。 Thus, when a subclass object is instantiated the subclass object must also automatically execute one of the constructors of the superclass.因此,当子类对象被实例化时,子类对象也必须自动执行超类的构造函数之一。

Cheers干杯

as constructor is not a part of class, so while calling it cannot be implemented, by using SUPER() we can call the members and memberfunctions in constructor.由于构造函数不是 class 的一部分,所以在调用它时无法实现,通过使用 SUPER() 我们可以调用构造函数中的成员和成员函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM