这是场景: -
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 要求,即可实现特定方法。它实际上并未创建该方法。
因此,通过继承获得方法实现的类具有该方法定义。此(单个)实现满足接口的要求。
在您的情况下:
-
Dog
扩展了Canine
,因此表示Canine
中的roam()
方法可用,如果不覆盖,则将作为方法暴露在狗对象上。 - 但随后
Dog
然后覆盖超类的方法,其自身对roam()
的定义。这是允许的,并且在Dog
上仍然只有一种称为roam()
的明确方法 - 新的替代。 -
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();
将执行狗的方法。