Java继承-调用超类方法

Posted

技术标签:

【中文标题】Java继承-调用超类方法【英文标题】:Java Inheritance - calling superclass method 【发布时间】:2011-10-17 07:29:38 【问题描述】:

假设我有以下两个类

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 而不是 beta 类中找到的 alphamethod1 逻辑?我可以使用super().alphaMethod1()

Eclipse IDE 中的 Autotype 让我可以从 alpha 类或 beta 类中选择 alphamethod1

【问题讨论】:

试试不带括号的 super。 super.alphaMethod1() 实际上。你为什么不试着看看会发生什么;)?此外,这个问题可能已经被问了数百次了...... 我知道这个问题现在已经很老了,但是如果您知道有任何重复,那么将该问题标记为重复。这现在是谷歌上的最高结果并且得到了很好的回答! 【参考方案1】:

你可以这样做:

super.alphaMethod1();

注意,super 是对父类的引用,而super() 是它的构造函数。

【讨论】:

有些在结尾调用超级方法,有些在开头为什么? 在构造函数中,您需要调用 super() 作为第一条语句(如果显式调用它)。在常规方法上,您可以根据您的应用程序逻辑需求在任何地方调用它。例如,如果您想在通话后添加额外的步骤,或者在最后添加额外的检查。 @MichałŠrajer 使用 super 您不能将类 alpha 中的方法调用到扩展类 betaTest 类中 作为一名 Java 初学者,我只是想知道为什么 super() 没有魔法知道它正在使用哪种方法(意思是:如果 foo() 调用 @987654330 @,很明显 super() 表示 super.foo()。构造函数在 Java 恕我直言中太特殊了)请参阅 Eiffel 中的 Precursor,它做得对。 附加信息:super.alphaMethod1(); 不能从 main 方法调用。这个答案没有说明它,但是这个调用需要从子类的某处 within 非静态上下文进行:beta.【参考方案2】:

只需使用super.alphaMethod1();

见super keyword in java

【讨论】:

【参考方案3】:

你不能使用 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();
   

【讨论】:

【参考方案4】:

可以使用 super 从母类调用方法,但这意味着你可能有设计问题。 也许B.alphaMethod1() 不应该覆盖A 的方法并被称为B.betaMethod1()

如果视情况而定,你可以放一些代码逻辑,如:

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

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

【讨论】:

【参考方案5】:

每当您创建子类对象时,该对象就具有父类的所有功能。 这里 Super() 是加入父母的设施。

如果你在那个时候写了 super() ,就会调用父母的默认构造函数。 如果你写超级,也一样。

this关键字引用当前对象,与访问父母的超级关键字工具相同。

【讨论】:

【参考方案6】:

解决方案在此答案的末尾,但在阅读之前您还应该阅读它之前的内容


您正在尝试做的事情会通过允许跳过覆盖方法中添加的可能验证机制来破坏安全性。

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

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 应该只存储 RED 项目。

无论我们使用以下哪个

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

打电话

box.put(new BlueItem());

将从RedItemsBox 调用put 方法(因为多态性)。所以它将正确阻止BlueItem对象被放置在RedItemBox中。

但是如果我们可以使用像 box.super.put(new BlueItem())这样的语法会发生什么?

在这里(假设它是合法的)我们将执行来自ItemBox 类的put 方法的版本。 但是该版本没有负责验证项目颜色的步骤。这意味着我们可以将 any Item 放入 RedItemBox

这种语法的存在意味着在子类中添加的验证步骤可以随时被忽略,使它们毫无意义。


在某些情况下,执行“原始”方法的代码是有意义的。

而那个地方是内部覆盖方法

请注意,ItemBox 和 RedItemBox 的 put 方法中的 cmets //(1) ..//(2).. 非常相似。实际上它们代表相同的动作...

因此,在覆盖方法中重用“原始”方法的代码是有意义的。 那个可以通过super.methodName(arguments)调用(比如从RedItemBox的put内部):

@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)
    

【讨论】:

【参考方案7】:

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

class Beta extends Alpha

  public void alphaMethod1()
  
    super.alphaMethod1();
  

【讨论】:

以上是关于Java继承-调用超类方法的主要内容,如果未能解决你的问题,请参考以下文章

Java基础-继承

java学习笔记(Core Java)5 继承

Java 中的继承——创建子类的对象也会调用超类的构造函数。为啥?

Java继承

使用超类引用调用重载的继承方法

java中阻止类的继承