这是一个父类
public class Parent {
public void f() {
}
}
这是一个简单的界面
public interface If {
public void f();
}
这是一个儿童班
public class Child extends Parent implements If{}
我的问题是:
虽然Child
声称实现了接口If
,但接口方法在Parent
中实现。为什么允许这样做?
答案 0 :(得分:9)
为什么允许这样做?
因为Child
符合合同。通过实现Child
,合同If
将提供一个公共f
函数,该函数不接受任何参数且没有返回值。它做到了。 它是如何它,在这种情况下通过从超类继承它,是无关紧要的。合同很满意,这一切都很重要。
接口方法在Parent
中实现
不是真的,它碰巧有f
方法。如果您执行If inst = new Parent()
,则会收到编译错误,因为Parent
并未说明它实现了If
(其上没有implements If
);实施If
不是其合同的一部分。另一方面,Child
提供该合同,因此If inst = new Child()
工作正常。
FWIW,你可能不会故意 ,但可以说没有任何问题。但是如果你想要使用的超类完全适合你想要实现的接口中的一个方法,它就会出现。
当发生这种情况时,您有三种选择:
什么都不做,让Parent
的方法直接实现接口方法。
覆盖Parent
的方法,即使你不会做任何不同的事情,例如:
@Override
public void f() {
super.f();
}
...除非您在调用Parent
f
f
之前或之后运行代码,否则实际上无法完成任何操作。
覆盖Parent
并自行实施,忽略Parent
的版本。但是,只有当f
的{{1}}与接口方法的f
完全不同 时才有意义 - 在这种情况下,您不应该是Parent
的子类{ {1}}首先,因为如果您根据界面的行为重新实现f
,那么f
将不再满足Parent#f
合同(就其行为而言)并且你将打破子类化的“是一个”规则。
所以,如果它有机地发生,选项1是完全合理的。你可能不会故意设置它。
答案 1 :(得分:2)
这是完全合法的,因为当您实施该方法时,它适用于两者。
从课堂角度和界面角度。单个实现既有两个目的,也没有任何歧义。
没有办法限制类或接口具有相同的方法签名,除非您与它们有关系,但在这种情况下不会出现问题。
答案 2 :(得分:0)
接口的要点是列出一组方法,这些方法可以在实现接口的类的任何对象上调用。
通过声明一个类实现一个接口,你声明可以在你的类上调用这组方法。
只要是这种情况(例如在您的示例中),就没有问题。