jvm如何对此做出反应

时间:2013-03-25 06:15:00

标签: java jvm

interface CanFight {
  void fight();
}

interface CanSwim {
  void swim();
}

interface CanFly {
  void fly();
}

class ActionCharacter {
  public void fight() {
      System.out.println("Inside class fight");
  }
}

class Hero extends ActionCharacter
    implements CanFight, CanSwim, CanFly {
  public void swim() {}
  public void fly() {}
}

      public class MultipleInterface {
  public static void t(CanFight x) { x.fight(); }
  public static void u(CanSwim x) { x.swim(); }
  public static void v(CanFly x) { x.fly(); }
  public static void w(ActionCharacter x) { x.fight(); }
  public static void main(String[] args) {
    Hero h = new Hero();
    t(h); // Treat it as a CanFight
    u(h); // Treat it as a CanSwim
    v(h); // Treat it as a CanFly
    w(h); // Treat it as an ActionCharacter
  }
}

JVM如何表现,因为我没有从canFight接口实现方法,但它是从ActionCharacter类获取的?它背后的逻辑是什么?要点是我没有定义在实现fight()接口时必须完成的方法canFight()

5 个答案:

答案 0 :(得分:3)

这不是JVM,而是Java编译器。 (如果JVM发现丢失的方法应该存在,那么你会得到一个NoSuchMethodException,但编译器不会让你达到那个点,除非你欺骗它。)

至于你的问题,声明方法的类或超类或接口无关紧要,只需要匹配名称和签名。因此,ActionCharacter#fightCanFight#fight声明了同样的事情。 Java没有区分这两者(既不是编译器也不是JVM /字节码格式)。

您的Herofight继承了ActionCharacter,但由于它恰好也与CanFight中定义的方法相匹配,因此它也可以兼作该接口的实现。< / p>

可以更清楚地更改方法名称(如果这些应该是两种不同的方法)或者ActionCharacter也实现CanFight(如果这确实是相同的方法)。

答案 1 :(得分:2)

如果一个类型实现了两个接口,并且每个接口定义了一个具有相同签名的方法,那么实际上只有一个方法,并且它们是不可区分的。

如果两个方法的返回类型相互冲突,则会出现编译错误。这是继承,方法重写,隐藏和声明的一般规则,并且还适用于不仅可能在2个继承的接口方法之间发生冲突,还可以应用于接口和超类方法之间的冲突,甚至只是由于泛型的类型擦除引起的冲突

JLS

中说
  

允许类中的单个方法声明   实现多个超接口的方法。

答案 2 :(得分:1)

您正在扩展ActionCharacter,这意味着您希望ActionCharacter的所有操作和属性都继承到您的Hero类。

这也包括fight操作。您将Hero标记为实施CanFight,但您继承了ActionCharacter的实际实施。

答案 3 :(得分:0)

Hero需要实现void figth();,但它会从ActionCharacter继承void figth();,因此符合要求。

答案 4 :(得分:0)

接口只声明一个方法,不能在接口中定义方法。所以这意味着你要在界面中提供你想要实现的草稿。

现在,你的类Hero继承了ActionCharacter类,它有一个public void fight()的定义。但是,这个fight()与CanFight的fight()无关。所以如果你在Hero中定义一个fight(),你将覆盖ActionCharacter的fight()。

由于你也实现了CanFight接口,jvm将允许你在CanFight中声明方法,但它将被视为ActionCharacter的fight()的覆盖。