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