【问题标题】:Why call super() in a constructor?为什么在构造函数中调用 super()?
【发布时间】:2012-05-17 11:55:54
【问题描述】:

我正在处理一个扩展 JFrame 的类。

这不是我的代码,它在开始构建 GUI 之前调用了super。我想知道为什么要这样做,因为我一直只是访问超类的方法而无需调用super();

【问题讨论】:

  • 旁注:扩展JFrame 可能不是您打算做的。扩展意味着一个 is-a 关系。除非您正在制作新的窗口组件,否则您可能应该扩展 JComponent

标签: java superclass


【解决方案1】:

有一个对super() 的隐式调用,对于所有具有父级的类(即Java 中的每个用户定义的类)都没有参数,因此通常不需要显式调用它。但是,可以使用对 super() 的调用和参数,如果父的构造函数接受参数,并且您希望指定它们。此外,如果父类的构造函数带参数,并且没有默认的无参数构造函数,则您将需要使用参数调用super()

一个例子,显式调用super() 可以让您对框架的标题进行一些额外的控制:

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

【讨论】:

【解决方案2】:

当您不自己做时,会自动调用父类的空构造函数super()。这就是您不必在代码中执行此操作的原因。它是为你完成的。

当您的超类没有无参数构造函数时,编译器将要求您使用适当的参数调用 super。编译器将确保您正确地实例化该类。所以这不是你需要过多担心的事情。

无论您是否在构造函数中调用super(),都不会影响您调用父类方法的能力。

作为旁注,有人说,为了清楚起见,通常最好手动进行调用。

【讨论】:

    【解决方案3】:

    我们可以使用 super 关键字访问超类元素

    假设我们有两个类,Parent 类和 Child 类,它们具有不同的方法 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();
            }
        }
    

    【讨论】:

      【解决方案4】:

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

      【讨论】:

      • 不回答问题,即“为什么”。不要对非代码文本使用代码格式。
      【解决方案5】:

      我们使用 super 关键字来调用超类的成员。

      由于子类从其父类继承所有成员(字段、方法、嵌套类),并且由于构造函数不是成员(它们不属于对象。它们负责创建对象),它们不会被子类继承.

      因此,如果我们需要为超类创建对象,我们必须显式调用父构造函数,以便构造函数链保持连接。在创建对象时,只能调用一个构造函数。通过super,我们可以在需要的时候从当前构造函数中调用另一个构造函数。

      如果你在想为什么它存在于一个不扩展任何其他类的类,那么请记住每个类默认都遵循对象类。因此,在构造函数中保留 super 是一个好习惯。

      注意:即使你的第一个语句中没有 super(),编译器也会为你添加它!

      【讨论】:

        【解决方案6】:

        以上答案都没有回答“为什么”。

        找到了很好的解释here

        子类可以有自己的私有数据成员,所以子类可以 也有自己的构造函数。

        子类的构造函数只能初始化实例 子类的变量。因此,当子类对象是 实例化的子类对象也必须自动执行一个 超类的构造函数。

        您可能还想阅读有关 super 关键字 here 的所有信息。

        【讨论】:

          【解决方案7】:

          我们可以使用 super 关键字访问超类成员

          如果您的方法覆盖其超类的方法之一,您可以通过使用关键字super 调用被覆盖的方法。您也可以使用 super 来引用隐藏字段(尽管不鼓励隐藏字段)。考虑这个类,超类:

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

          // 这里是一个子类,叫做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();    
              }
          }
          

          在子类中,简单名称printMethod() 指的是子类中声明的名称,它覆盖了超类中的名称。因此,要引用继承自 Superclass 的 printMethod(),Subclass 必须使用限定名称,如图所示使用 super。编译和执行子类会打印以下内容:

          Printed in Superclass.
          Printed in Subclass
          

          【讨论】:

          • 第一句话不正确,这些都不能回答问题。
          猜你喜欢
          • 2017-03-18
          • 1970-01-01
          • 2019-11-17
          • 2021-05-07
          • 1970-01-01
          • 1970-01-01
          • 2017-04-01
          • 2013-04-25
          • 2015-01-27
          相关资源
          最近更新 更多