简体   繁体   English

jvm如何对此做出反应

[英]How does jvm react to this

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
  }
}

How does JVM behave as I am not implementing method from canFight interface but it takes it from ActionCharacter class? 如何JVM表现得像我不是从实现方法canFight接口,但它需要从ActionCharacter类? What is the logic behind it? 它背后的逻辑是什么? Point is I am not defining method fight() that must be done if implementing canFight() interface. canFight()是我没有定义方法fight() ,如果实现canFight()接口必须完成。

It's not the much the JVM, but the Java compiler. 它不是JVM,而是Java编译器。 (If the JVM finds a method missing that should be there, you get a NoSuchMethodException, but the compiler won't let you get to that point unless you trick it). (如果JVM发现缺少的方法应该存在,那么你会得到一个NoSuchMethodException,但编译器不会让你达到那个点,除非你欺骗它)。

As for your question, it does not matter which class or superclass or interface a method is declared in, only the name and signature need to match. 至于你的问题,声明方法的类或超类或接口无关紧要,只需要匹配名称和签名。 Thus, ActionCharacter#fight and CanFight#fight declare the same thing. 因此, CanFight#fight ActionCharacter#fightCanFight#fight声明了同样的事情。 Java makes no distinction between the two (neither the compiler nor the JVM/bytecode format). Java在两者之间没有区别(既不是编译器也不是JVM /字节码格式)。

Your Hero inherits fight from ActionCharacter , but since it happens to also match the method defined in CanFight , it also doubles as an implementation of that interface. 你的Hero继承fightActionCharacter ,但因为它正好也匹配定义的方法CanFight ,还兼作该接口的实现。

Could be clearer to either change the method name (if those are supposed to be two different methods) or have ActionCharacter also implement CanFight (if this is indeed intended to be the same method). 可以更清楚要么改变方法名(如果这些都应该是两种不同的方法),要么有ActionCharacter还实现CanFight (如果这确实是有意相同的方法)。

If a type implements two interfaces, and each interface define a method that has identical signature, then in effect there is only one method, and they are not distinguishable. 如果一个类型实现两个接口,并且每个接口定义一个具有相同签名的方法,那么实际上只有一个方法,并且它们是不可区分的。

If, say, the two methods have conflicting return types, then it will be a compilation error. 例如,如果两种方法具有冲突的返回类型,那么它将是编译错误。 This is the general rule of inheritance, method overriding, hiding, and declarations, and applies also to possible conflicts not only between 2 inherited interface methods, but also an interface and a super class method, or even just conflicts due to type erasure of generics. 这是继承,方法重写,隐藏和声明的一般规则,并且还适用于不仅可能在2个继承的接口方法之间发生冲突,还可以应用于接口和超类方法之间的冲突,甚至只是由于泛型的类型擦除引起的冲突。

It's said in JLS 它在JLS中说过

It is permitted for a single method declaration in a class to implement methods of more than one superinterface. 允许类中的单个方法声明实现多个超接口的方法。

You are extending ActionCharacter which means you want all the operations and attributes of ActionCharacter inherited to your Hero class. 您正在扩大ActionCharacter这意味着你希望所有的操作和属性ActionCharacter继承你的Hero类。

This include fight operation as well. 这也包括fight行动。 You mark Hero as implementing CanFight but you inherit the actual implementation from ActionCharacter . 你记住Hero为实现CanFight但你继承从实际执行ActionCharacter

Hero is required to implement void figth(); Hero需要实现void figth(); but it inherits void figth(); 但它继承了void figth(); from ActionCharacter so the requirement is met. 来自ActionCharacter,因此符合要求。

Interfaces only declares a method , you cannot define a method in an interface. 接口只声明一个方法,不能在接口中定义方法。 So what it means is that you give a draft of what you want to implement in an interface. 那么这意味着您要在接口中提供要实现的内容的草稿。

Now here, your class Hero inherits class ActionCharacter which has a definition of public void fight(). 现在,你的类Hero继承了ActionCharacter类,它有一个public void fight()的定义。 However, this fight() has no connection with fight() of CanFight. 但是,这个fight()与CanFight的fight()无关。 so if you define a fight() in Hero, you will override the fight() of ActionCharacter. 所以如果你在Hero中定义一个fight(),你将覆盖ActionCharacter的fight()。

Since you also implement the interface CanFight, jvm will allow this as you have declared the method in CanFight, but it will be treated as override of fight() of ActionCharacter. 由于你也实现了CanFight接口,jvm将允许你在CanFight中声明方法,但它将被视为ActionCharacter的fight()的覆盖。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM