0

当我们在一个类中实现一个接口时,我们需要确保该接口定义的所有方法都出现在类的源代码中。那么为什么这段代码容易编译呢?

interface A {
    void f();
}
class X {
    public void f() {}
}
class Y extends X implements A {
}
4

5 回答 5

5

因为X已经实现了f()方法Yextends X,这使得它继承了该方法的实现。

对于这种情况,解决方法是方法签名。并且 class X,即使没有实现 A 接口,也有一个具有正确签名的方法。所以实现类Y也有那个方法。

X我想说的是,只有在没有办法让类也实现接口(外部库、代码冻结、坏老板等)时才应该使用这样的构造——虽然有效——因为它让人有些头疼发生了什么...阅读代码的人必须导航到该类X,并在那里找到f()方法...

首先,我误读了这个问题,这些问题在X implements A出现时也是有效的。
即使您明确指定了该X implements A子句,也没关系 - 在这种情况下这是多余的。

如果X是抽象的,并且Y没有实现f()Y将被迫实现该方法,除非Y也被声明为抽象的。

于 2013-10-14T06:50:36.113 回答
2

如果某些接口方法没有在派生类中实现,但在基类中存在,则将使用基类中的实现。

界面

interface A {
    void f();
}

基类

class X {
    public void f() {}
}

编译器在这里检查 method f(),如果它的定义没有写在同一个类中,那么它将在基类中查找定义。这是继承的基本属性

派生类

class Y extends X implements A {
   

}

您可以将其理解为f()间接存在于课堂Y上。

首先编译器会读取类Y,然后它会转到接口,然后它会在类中A 搜索方法。如果它没有写在那里,那么它将在基类中搜索,即f()Yx

于 2013-10-14T06:52:00.257 回答
0

从哪里得到它必须在类的源代码中的声明?

一个类必须实现由已实现interface或父 ( abstract)定义的所有方法,class否则必须声明abstract

所以当然 Y 类会编译。

于 2013-10-14T06:52:36.197 回答
0

java中的简单概念是子继承其父的属性,如果是这种情况则Y已经f()可用。这不是魔术。

于 2013-10-14T06:54:29.703 回答
0

尽管类X没有实现接口A,但它确实有一个恰好与接口方法签名匹配的公共方法。当类Y扩展类X时,它会继承该方法,编译器会将其视为接口方法的有效实现。

于 2013-10-14T06:55:02.993 回答