当我们在类中实现接口时,我们需要确保该接口定义的所有方法都出现在类的源代码中。那么为什么这段代码很容易编译?
interface A {
void f();
}
class X {
public void f() {}
}
class Y extends X implements A {
}
答案 0 :(得分:5)
由于X
已经实现了f()
方法,Y
扩展了X
,这使得它继承了所述方法的实现。
对于这种情况,分辨率通过方法签名进行。类X
即使没有实现A接口,也有一个具有正确签名的方法。所以实现类Y
也有这个方法。
我会说只有当没有办法使类X
也实现接口(外部库,代码冻结,坏老板等)时才应该使用这样的结构 - 虽然有效 - ,因为它让人头疼不已......正在阅读代码,必须导航到课程X
,并在那里找到f()
方法......
首先我误解了这个问题,这些问题在X implements A
出现时也是有效的
即使你已经明确地指定了 X implements A
子句,这也没关系 - 在这种情况下是多余的。
如果X
是抽象的,并且Y
没有实现f()
,则Y
将被强制实施该方法,除非Y
被声明为抽象太
答案 1 :(得分:2)
如果某个接口方法没有在派生类中实现,但它在基类中,那么将使用基类的实现。
interface A {
void f();
}
class X {
public void f() {}
}
这里编译器检查方法f()
,如果它的定义没有写在同一个类中,那么它将在基类中查找定义。 这是继承的基本属性
class Y extends X implements A {
}
您可以将其理解为f()
间接出现在课程Y
中。
第一个编译器将读取类Y
,然后它将转到接口A
,然后它将在类f()
中搜索方法Y
。如果它没有写在那里那么它将在基类中搜索,即x
答案 2 :(得分:0)
从那里你得到的声明它必须在类的源代码中?
一个类必须实现由已实现的interface
或父(abstract
)class
定义的所有方法,否则必须声明为abstract
。
所以当然Y类会编译。
答案 3 :(得分:0)
java中的简单概念是子级继承其父级的属性,如果是这种情况,那么Y
已经有f()
可用。这不是魔术。
答案 4 :(得分:0)
虽然类 X 没有实现接口 A ,但它确实有一个恰好与接口方法签名匹配的公共方法。 当类 Y 扩展类 X 时,它继承该方法,编译器会将其视为接口方法的有效实现。