简体   繁体   中英

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? What is the logic behind it? Point is I am not defining method fight() that must be done if implementing canFight() interface.

It's not the much the JVM, but the Java compiler. (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).

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. Java makes no distinction between the two (neither the compiler nor the JVM/bytecode format).

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.

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

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.

It's said in 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.

This include fight operation as well. You mark Hero as implementing CanFight but you inherit the actual implementation from ActionCharacter .

Hero is required to implement void figth(); but it inherits void figth(); from ActionCharacter so the requirement is met.

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(). However, this fight() has no connection with fight() of CanFight. so if you define a fight() in Hero, you will override the fight() of ActionCharacter.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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