Java继承 - 调用超类方法

时间:2011-08-01 09:30:08

标签: java inheritance methods superclass

假设我有以下两个类

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让我可以从课程alphamethod1或课程alpha中选择beta

7 个答案:

答案 0 :(得分:76)

你可以这样做:

super.alphaMethod1();

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

答案 1 :(得分:19)

只需使用super.alphaMethod1();

即可

请参阅super keyword in java

答案 2 :(得分:12)

你不能通过使用beta的对象调用alpha的alphaMethod1()但你有两个解决方案:

解决方案1:从测试版的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();
   }
}

答案 3 :(得分:4)

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

如果它取决于具体情况,你可以设置一些代码逻辑,如:

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

像这样,它只会在需要时调用A的方法,对类用户来说仍然是不可见的。

答案 4 :(得分:3)

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

如果你在那个时候编写super(),则调用父类的默认构造函数。 如果你写超级相同的话。

此关键字引用与访问父母的超级关键字facilty相同的当前对象。

答案 5 :(得分:1)

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


您尝试执行的操作会允许跳过在覆盖方法中添加的可能验证机制,从而破坏安全性。

现在让想象我们可以通过像

这样的语法从超类调用方法的版本
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());

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

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

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

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


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

那个地方是在覆盖方法中

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

因此在覆盖方法中重用来自“原始”方法的代码是有意义的。 并且可以通过 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)
    }
}

答案 6 :(得分:0)

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

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