我创建了一个名为parent
的父类,其中包含show()
方法
和一个接口my
具有相同的默认show()
方法,具有不同的主体。然后我创建了一个继承接口my
的子类并实现它。
class Parent
{
public void show()
{
System.out.println("parent");
}
}
interface Interface
{
default void show()
{
System.out.println("interface");
}
}
class Child extends Parent implements Interface
{
public static void main(String[] args)
{
Child child = new Child();
child.show();
}
}
如果在jdk 8中运行它,您将看到输出为parent
父字符串。
问题是扩展和继承实现相同方法的基类和接口不应该是一个歧义错误吗?
答案 0 :(得分:1)
如果在接口中有方法show()
,则实现该接口的类必须覆盖它并提供自己的实现。但这里有默认实现。
此类Child
通过继承从show()
获取方法Parent
。因此,界面中的方法就像在类Child
中重写一样。
您不应该认为show()
属于班级Parent
,而是将其视为班级Child
编辑:即使您将child
对象转换为Interface
类型,
Interface interface = (Interface)child;
interface.show()
会在show()
课程中调用Child
的实施,这是show()
中继承的Parent
(因此会打印parent
)
答案 1 :(得分:0)
当您在Child类对象上调用show()
方法时,它会调用父类的show()
方法,因为当您扩展具有公共方法的类时,它也属于子类。
由于您正在实现界面,并且在您的班级show()
中存在,因此您隐藏了界面show()
方法。
答案 2 :(得分:0)
首先需要了解从超类继承的含义。
在您的代码中,Child继承Parent。这意味着 all 将父级的内容“移动”到Child。所以孩子班就像这样
class Child implements Interface
{
public static void main(String[] args)
{
Child child = new Child();
child.show();
}
public void show()
{
System.out.println("parent");
}
}
请注意,子类现在具有名为show
的方法。当然,上面的代码会导致歧义吗?当然不是! Child中的show
方法会覆盖Interface
中的默认实现!
因此,下次遇到这种情况时,只需将继承视为“将超类中的所有内容移动到子类”,您就会理解为什么。
答案 3 :(得分:0)
这符合spec有充分理由。
将默认方法添加到Interface
不应该破坏Child
的实现。
如果尝试继承两个默认方法,则会出现歧义错误。有关如何解决此问题,请参阅http://www.angelikalanger.com/Lambdas/LambdaTutorial/lambdatutorial_5.html#Ambiguity。