何时使用super()?

88

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

编辑:
我找到了一个示例代码,其中使用了super.variable

class A
{
    int k = 10;
}

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

我理解在这里,你必须使用super来访问超类中的k变量。但是,在任何其他情况下,super();单独使用会做些什么呢?


32
实际上,在这个例子中,不需要使用super来引用k。可以直接引用k。只有当你在Test类中声明了另一个名为k的字段(Test.k)时,才需要使用super来访问A.k - Mark Peters
11个回答

151

在调用构造方法中,仅仅使用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
假设一个方法在子类中被覆盖,然后在其子类中再次被覆盖(多级继承)。如果我们需要在孙子类中同时调用祖父和父类的方法,那么该如何使用super关键字呢? - h8pathak
3
如果您正在询问子类如何绕过其父类的实现但调用祖先,则在Java中不可能实现。 - Mark Peters

45

super 用于调用父类的 构造函数方法属性


25

当你在子类中覆盖了一个来自父类的方法,但又想要调用父类的该方法时,你可以使用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

1
你的主方法声明行中是不是有 (String[] args)?非常感谢! - Appalachian Math

11
您可以将它用作子类构造函数的第一行,以调用其父类的构造函数。
例如:
public class TheSuper{
    public TheSuper(){
        eatCake();
    }
}

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

创建TheSub的一个实例会同时调用eatCake()eatMoreCake()


9

4
如链接中所述,您永远不必调用 super(),因为Java会隐式添加它。但是如果您需要一个非默认父级构造函数,则必须调用 super(args) - Michael Brewer-Davis

1
你可以使用它来调用父类的方法(例如在覆盖该方法时,super.foo()等) - 这将允许您保留该功能,并添加到覆盖方法中的任何其他内容。

1

你的链接已经失效。 - ArtOfWarfare

1

你可以使用super()来调用父类的构造函数。由于一个类可以有多个构造函数,你可以使用super()super(param,param)来调用特定的构造函数,也可以让Java处理并调用标准构造函数。请记住,遵循类层次结构的类遵循“is-a”关系。


0

来自Oracle文档page

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

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

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

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

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

super();  

或者:

super(parameter list);

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

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

相关文章:

多态 vs 重写 vs 重载


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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接