什么时候使用super()?


80

我目前正在Java课程中学习有关类继承的信息,但我不知道何时使用该super()调用?

编辑:
我发现使用此代码示例:super.variable

class A
{
    int k = 10;
}

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

因此,我知道在这里,您必须使用它super来访问k超类中的变量。但是,在其他情况下,该怎么super();办?在其自己的?


30
实际上,在此示例super中不需要引用kk可以直接引用。 super只需要访问A.k,如果你声明的命名另一场kTestTest.k)。
Mark Peters,2010年

Answers:


143

精确 调用始终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");
    }
}

2
假设方法在子类中被重写,然后再次在其子类中被重写。(多级继承)如果必须同时将祖父母和父母的方法调用到孙子类中该怎么办。超级将如何使用?
h8pathak 2015年

1
@ h8pathak:如果您要问子类如何绕过其父类的实现而调用祖父母,那么在Java中是不可能的。
马克·彼得斯

44

super是用来打电话的constructormethodsproperties父类的。


22

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()调用print()超类的方法CellPhone。输出将是:

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

1
在您的主要方法声明行中是(String [] args)吗?非常感谢!
阿巴拉契亚数学


9

您可以将其用作子类构造函数的第一行,以调用其父类的构造函数。

例如:

public class TheSuper{
    public TheSuper(){
        eatCake();
    }
}

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

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


1

您可以使用它来调用超类的方法(例如,当您覆盖此类方法时,super.foo()等)-这将允许您保留该功能并使用覆盖的其他功能添加到该类上。方法。



1

您调用super()以专门运行您的超类的构造函数。由于一个类可以有多个构造函数,你可以使用特定的构造函数或者调用super()super(param,param)奥得可以让Java的句柄,并调用标准的构造。请记住,遵循类层次结构的类遵循“是”关系。


0

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


不对。它会自动发生。
马克·彼得斯

即使没有默认构造函数?它怎么知道通过什么?
robev

如果没有默认构造函数,则需要调用super(some args),而不是super()。但问题是,“必须”是错误的。只要编译该类,就可以确保调用其父类的构造函数之一。
马克·彼得斯

我没有说清楚,当我编写super()时,我并不是说没有参数的构造函数,我只是不想编写任何参数。是的,我的意思是您需要调用它,否则它将无法编译,这就是为什么我说必须这样做。
罗布夫

1
再一次,如果父类中存在无参数构造函数,则无需显式调用超级构造函数。超级构造函数将始终被调用,而您的措辞使您听起来好像有危险:如果不使用超级构造函数,则不被调用super(...)。只是它无法编译的危险。
马克·彼得斯

0

我只是试了一下,评论了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();
    }
}

0

从oracle文档页面

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

您还可以使用它super来引用隐藏字段(尽管不建议使用隐藏字段)。

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

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

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

super();  

要么:

super(parameter list);

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

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

相关文章:

多态性vs覆盖vs重载

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.