【问题标题】:When do I use super()?什么时候使用 super()?
【发布时间】:2011-05-04 16:47:41
【问题描述】:

我目前正在学习 Java 课程中的类继承,但我不明白何时使用 super() 调用?

编辑:
我发现了这个使用super.<em>variable</em>的代码示例:

class A
{
    int k = 10;
}

class Test extends A
{
    public void m() {
        System.out.println(super.k);
    }
}

所以我明白这里,你必须使用super 来访问超类中的k 变量。但是,在任何其他情况下,super(); 做什么?靠自己?

【问题讨论】:

  • 实际上,在这个例子中super不需要引用kk 可以直接引用。仅当您在 Test (Test.k) 中声明了另一个名为 k 的字段时,才需要 super 访问 A.k

标签: java inheritance super


【解决方案1】:

准确地调用super()总是是多余的。它明确地做了其他情况下会隐含地做的事情。这是因为如果你省略了对超级构造函数的调用,那么无论如何都会自动调用无参数的超级构造函数。并不是说它的风格不好;有些人喜欢直言不讳。

然而,当超级构造函数接受你想从子类传入的参数时,它变得有用。

public class Animal {
   private final String noise;
   protected Animal(String noise) {
      this.noise = noise;
   }

   public void makeNoise() {
      System.out.println(noise);
   }
}

public class Pig extends Animal {
    public Pig() {
       super("Oink");
    }
}

【讨论】:

  • 假设一个方法在子类中被覆盖,然后在其子类中再次被覆盖。 (多级继承)如果我们必须同时将祖父母和父母的方法调用到孙子类中怎么办。超级怎么用?
  • @h8pathak:如果您要问子类如何绕过其父类的实现但调用祖父类,这在 Java 中是不可能的。
【解决方案2】:

super用于调用父类的constructormethodsproperties

【讨论】:

    【解决方案3】:

    当您在子类中重写父类的方法时,您也可以在子类中使用super 关键字。

    示例:

    public class CellPhone {
        public void print() {
            System.out.println("I'm a cellphone");
        }
    }
    
    public class TouchPhone extends CellPhone {
        @Override
        public void print() {
            super.print();
            System.out.println("I'm a touch screen cellphone");
        }
        public static void main (strings[] args) {
            TouchPhone p = new TouchPhone();
            p.print();
        }
    }
    

    这里,super.print() 行调用超类CellPhoneprint() 方法。输出将是:

    I'm a cellphone
    I'm a touch screen cellphone
    

    【讨论】:

    • 是 (String[] args) 在你的主要方法声明行吗?非常感谢!
    【解决方案4】:

    你可以用它作为子类构造函数的第一行来调用其父类的构造函数。

    例如:

    public class TheSuper{
        public TheSuper(){
            eatCake();
        }
    }
    
    public class TheSub extends TheSuper{
        public TheSub(){
            super();
            eatMoreCake();
        }
    }
    

    构造TheSub 的实例将同时调用eatCake()eatMoreCake()

    【讨论】:

      【解决方案5】:

      当您希望调用超类构造函数时 - 初始化其中的字段。看看这篇文章,了解何时使用它:

      http://download.oracle.com/javase/tutorial/java/IandI/super.html

      【讨论】:

      • 正如链接中所说,您永远必须调用super(),因为Java 会隐式添加它。但是如果你需要一个非默认的父构造函数,你必须调用super(args)
      【解决方案6】:

      您可以使用它来调用超类的方法(例如,当您覆盖这样的方法时,super.foo() 等)——这将允许您保留该功能并添加您拥有的任何其他功能在被覆盖的方法中。

      【讨论】:

        【解决方案7】:

        【讨论】:

        • 您的链接已失效。
        【解决方案8】:

        您调用super() 专门运行您的超类的构造函数。鉴于一个类可以有多个构造函数,您可以使用super()super(param,param) 调用特定的构造函数,或者您可以让Java 处理它并调用标准构造函数。请记住,遵循类层次结构的类遵循“is-a”关系。

        【讨论】:

          【解决方案9】:

          子类的构造函数的第一行必须是对super()的调用,以确保调用超类的构造函数。

          【讨论】:

          • 不正确。它会自动发生。
          • 即使没有默认构造函数?它怎么知道要传递什么?
          • 如果没有默认构造函数,则需要调用super(some args),而不是super()。但关键是,“必须”是错误的。 保证只要类编译,超类的构造函数之一就会被调用。
          • 我没有说清楚,当我写 super() 的时候,我的意思不是没有参数的构造函数,我只是不想写任何东西。是的,我的意思是你需要调用它,否则它不会编译,这就是我说必须的原因。
          • 再一次,如果父类中存在无参数构造函数,则不需要显式调用超级构造函数。超级构造函数将总是被调用,而你的措辞听起来像是如果你不把super(...) 放入超级构造函数而不被调用的危险。绝对没有危险其中;只是有无法编译的危险。
          【解决方案10】:

          我刚试过,评论 super();做同样的事情而不像@Mark Peters 所说的那样发表评论

          package javaapplication6;
          
          /**
           *
           * @author sborusu
           */
          public class Super_Test {
              Super_Test(){
                  System.out.println("This is super class, no object is created");
              }
          }
          class Super_sub extends Super_Test{
              Super_sub(){
                 super();
                 System.out.println("This is sub class, object is created");
              }
              public static void main(String args[]){
                  new Super_sub();
              }
          }
          

          【讨论】:

            【解决方案11】:

            来自 oracle 文档page

            如果您的方法覆盖其超类的方法之一,您可以通过使用关键字super 调用被覆盖的方法。

            您也可以使用super 来引用隐藏字段(尽管不鼓励隐藏字段)。

            在子类的构造函数中使用super

            超类构造函数的调用必须是子类构造函数的第一行。

            调用超类构造函数的语法是

            super();  
            

            或:

            super(parameter list);
            

            使用super(),调用超类无参数构造函数。使用super(parameter list),调用具有匹配参数列表的超类构造函数。

            注意:如果构造函数没有显式调用超类构造函数,Java 编译器会自动插入对超类的无参数构造函数的调用。如果超类没有无参数构造函数,则会出现编译时错误。

            相关帖子:

            Polymorphism vs Overriding vs Overloading

            【讨论】:

              猜你喜欢
              • 2014-03-27
              • 1970-01-01
              • 2011-11-28
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2014-06-04
              • 2017-09-13
              • 1970-01-01
              相关资源
              最近更新 更多