通过继承和接口两次,可以在类中存在相同的方法



这是场景: -

class Canine{
  public void roam(){
    System.out.println("Canine-Roam");
  }
}
public interface Pet{    
  public abstract void roam();
}

class Dog extends Canine implements Pet{
  public void roam(){
    System.out.println("Dog Roam");
  }
  public static void main(String [] args){
    Dog adog = new Dog();
    adog.roam();
  }
}

我知道,JVM在选择运行哪种方法时一定没有任何困惑,这意味着哪种方法过度缠绕。但是我还是很困惑。为什么此程序编译?

no-同一方法在类中不存在两次。

一个接口只需声明A 要求,即可实现特定方法。它实际上并未创建该方法。

因此,通过继承获得方法实现的类具有该方法定义。此(单个)实现满足接口的要求。

在您的情况下:

  1. Dog扩展了Canine,因此表示Canine中的roam()方法可用,如果不覆盖,则将作为方法暴露在狗对象上。
  2. 但随后 Dog然后覆盖超类的方法,其自身对roam()的定义。这是允许的,并且在Dog上仍然只有一种称为roam()的明确方法 - 新的替代。
  3. Dog实现Pet,这意味着需要使用roam()方法。它确实 - 因此是此接口的有效实现。

您的情况完全很好,它将运行良好并输出Dog Roam。这意味着Dog类中的功能运行。

您没有遇到任何编译时间错误,因为狗中的方法正在接口中实现抽象方法声明,并且偶然地,此方法的方法签名与父类匹配。

<</p>

我认为您混淆了两件事:

  • 实现:做了什么?请参阅:Canine.roam()Dog.roam()
  • 接口:您如何调用它?请参阅:Pet.roam()

很明显,您在两个类中有两个roam()的"实现":

  • Canine.roam()
  • Dog.roam()

从不

并且由于Dog扩展了Canine,因此方法Canine.roam()被覆盖了。您的main()功能使用 Dog.roam()

您已经为狗类型创建了对象并将其分配给狗参考类型。
推翻,这里无关。尽管您从犬类中扩展了狗课,但两种都是不同类型的类型。
在编译时,编译器检查参考类型中是否存在方法定义。就是这样。它必须在那里出现。在运行时,JVM首先检查参考类型中的方法,然后发现在"参考类型"子类中存在的相同方法上是否有任何骑行版本。
如果存在,它将被执行。否则,将执行参考类型的方法。

即。

Canine c=new Dog(); 

将执行狗的方法。

最新更新