Java继承 - 调用超类方法

77
假设我有以下两个类:
public class alpha {

    public alpha(){
        //some logic
    }

    public void alphaMethod1(){
        //some logic
    }
}

public class beta extends alpha {

    public beta(){
        //some logic
    }

    public void alphaMethod1(){
        //some logic
    }
}

public class Test extends beta
{
     public static void main(String[] args)
      {
        beta obj = new beta();
        obj.alphaMethod1();// Here I want to call the method from class alpha.
       }
}
如果我初始化一个类型为beta的新对象,如何执行在alpha类中找到的alphamethod1逻辑而不是beta类中的呢?我可以使用super().alphaMethod1()吗?<-我想知道这是否可行。 在Eclipse IDE中,Autotype给了我从alpha类或beta类中选择alphamethod1的选项。

2
尝试不带括号使用超级函数。 - Jacob
3
“super.alphaMethod1()”,为了尝试一下,为什么不直接试试看呢 ;)?此外,这个问题可能已经被问了数百次了... - Tedil
3
我知道这个问题现在很老了,但如果你知道有任何重复的问题,请将该问题标记为重复。现在它是谷歌搜索的最佳结果,并得到了很好的回答! - mattumotu
7个回答

126

你可以这样做:

super.alphaMethod1();

注意,super 是指向父类的引用,而 super() 则是父类的构造函数。


有些人在最后调用超级方法,有些人在最开始调用,为什么? - Asif Mushtaq
2
在构造函数中,如果你显式地调用 super(),则需要将其作为第一条语句调用。在常规方法中,您可以根据应用逻辑需求随时调用它。例如,如果您想在调用后添加额外的步骤,则可以在开头调用它,如果要添加额外的检查,则可以在结尾处调用它。 - Michał Šrajer
2
@MichałŠrajer 使用 super 无法将类 alpha 中的方法调用到扩展类 betaTest 类中。 - Rudra
作为Java初学者,我只是想知道为什么super()没有魔力可以知道它在哪个方法中使用(意思是:如果foo()调用super(),那么很明显super()表示的是super.foo()。在Java中,构造函数太特殊了)。请参见Eiffel中的Precursor,在那里做得很好。 - U. Windl
1
额外信息:super.alphaMethod1(); 不能从 main 方法中调用。这个答案没有说明,但是这个调用需要在子类 beta 的非静态上下文中的某个地方进行。 - Pshemo
@Michal,这个答案完全是错的。如果你使用super.alphaMethod1(),编译器会报错说“无法从静态上下文调用,使main非静态”。这个答案怎么会被点赞? - abc123

22

20

您不能使用beta对象来调用alpha的alphaMethod1()方法,但是有两种解决方案:

解决方案1:从beta的alphaMethod1()方法中调用alpha的alphaMethod1()方法。

class Beta extends Alpha
{
  public void alphaMethod1()
  {
    super.alphaMethod1();
  }
}

或从类似 Beta 的其他任何方法中:

class Beta extends Alpha
{
  public void foo()
  {
     super.alphaMethod1();
  }
}

class Test extends Beta 
{
   public static void main(String[] args)
   {
      Beta beta = new Beta();
      beta.foo();
   }
}
解决方法2: 创建alpha的对象并调用alpha的alphaMethod1()方法。
class Test extends Beta
{
   public static void main(String[] args)
   {
      Alpha alpha = new Alpha();
      alpha.alphaMethod1();
   }
}

5

可以使用super来调用父类的方法,但这可能意味着您可能存在设计问题。也许B.alphaMethod1()不应该覆盖A的方法,而应该被称为B.betaMethod1()。

如果情况有所不同,您可以添加一些代码逻辑,比如:

public void alphaMethod1(){
    if (something) {
        super.alphaMethod1();
        return;
    }
    // Rest of the code for other situations
}

像这样,只有在需要时才会调用A的方法,并且对于类用户将保持不可见。

3

本答案的解决方案在结尾,但在阅读解决方案之前,您应该先阅读它之前的内容


您试图做的事情将会破坏安全性,因为它允许跳过覆盖方法中可能添加的验证机制。

现在让我们想象一下,我们可以通过以下语法调用超类中的方法版本:

referenceVariable.super.methodName(arguments)

如果我们有这样的类:
class ItemBox{ //can sore all kind of Items
    public void put(Item item){
        //(1) code responsible for organizing items in box 
    }

    //.. rest of code, like container for Items, etc.
}

class RedItemsBox extends ItemBox {//to store only RED items

    @Override
    public void put(Item item){ //store only RED items
        if (item.getColor()==Color.RED){
            //(2) code responsible for organizing items in box
        }
    }
}

你会发现RedItemsBox只应存储红色物品。

无论我们使用以下哪个:

ItemBox     box = new RedItemsBox();
RedItemsBox box = new RedItemsBox();

调用

box.put(new BlueItem());

将从RedItemsBox调用put方法(由于多态性)。 因此,它将正确地防止在RedItemBox中放置BlueItem对象。 但是如果我们可以使用以下语法会发生什么 box.super.put(new BlueItem())
在这里(假设它是合法的),我们将执行ItemBox类的put方法版本。 但是,该版本没有负责验证项目颜色的步骤。这意味着我们可以将任何Item放入RedItemBox中。
存在这样的语法意味着可以随时忽略子类中添加的验证步骤,使它们变得无意义。

确实有一种情况下执行“原始”方法的代码是有意义的。

那个地方是覆盖方法内部

请注意,ItemBoxRedItemBoxput方法中的注释//(1) ..//(2)..非常相似。 实际上,它们代表相同的操作......

因此,在覆盖方法内部重用“原始”方法中的代码是有意义的。 并且可以通过super.methodName(arguments)调用(例如从RedItemBoxput内部)来实现。

@Override
public void put(Item item){ //store only RED items
    if (item.getColor()==Color.RED){
        super.put(item); // <<<--- invoking code of `put` method 
                         //        from ItemBox (supertype)
    }
}

2
无论何时您创建子类对象,该对象都具有父类的所有功能。在这里,Super()是访问父类的工具。
如果您在此时编写super(),则会调用父级的默认构造函数。 同样,如果您写入super。
此关键字引用当前对象,与super关键字访问父级的工具相同。

0

beta obj = new beta(); 由于您已经创建了beta对象,因此无法直接引用alpha对象的alphamethod1。 可以修改为

class Beta extends Alpha
{
  public void alphaMethod1()
  {
    super.alphaMethod1();
  }
}

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