我有两个Java接口和一个实现类。
(我已经使用Eclipse直接运行程序,并且我没有尝试通过从命令行显式编译来检查任何编译器警告等。)
为什么他们没有问题?为什么Java允许这样做,即使它满足两个接口的“契约”但是在实现类时产生歧义?
更新了示例。
public interface CassettePlayer {
void play();
}
public interface DVDPlayer {
void play();
}
public class CarPlayer implements CassettePlayer,DVDPlayer{
@Override
public void play() {
System.out.println("This plays DVD, screw you Cassette !");
}
public static void main(String args[]) {
CarPlayer cp = new CarPlayer();
cp.play();
CassettePlayer firstInterface = new CarPlayer();
firstInterface.play();
DVDPlayer secondInterface = new CarPlayer();
secondInterface.play();
}
}
答案 0 :(得分:38)
Java Language Specification, section 8.1.5中特别允许此方案:
允许类中的单个方法声明实现多个超接口的方法。例如,在代码中:
interface Fish { int getNumberOfScales(); } interface Piano { int getNumberOfScales(); } class Tuna implements Fish, Piano { // You can tune a piano, but can you tuna fish? int getNumberOfScales() { return 91; } }
类
getNumberOfScales
中的方法Tuna
具有与接口Fish
中声明的方法匹配的名称,签名和返回类型,并且还与接口{{1}中声明的方法匹配};它被认为是实现两者。
然后文本继续注意,如果方法签名具有不同的返回类型,例如Piano
和double
,则无法在同一个类和编译中实现这两个接口时间错误会产生。
答案 1 :(得分:5)
对于这个问题,有必要了解接口的用途。
接口是一种“契约”,因此人们知道在具有该接口的类中强制实现哪些方法。
因此,如果您需要一个实现“DVDPlayer”的类(因为您需要方法“play()”),您将找到CarPlayer。同样需要一个实现CassettePlayer的Class。这是技术性的解释。
但是当然在你的语义编码中你应该确保CarPlayer的方法“play()”满足DVDPlayer和CassettePlayer的语义。我认为在实际应用中这将是一个不好的做法。
当然在你的例子中,有两个接口声明相同的方法是一个坏主意。更实际的是,您应该使用方法“play()”创建一个“Player”接口,并且还有另外两个更具体的接口DVDPlayer和CassettePlayer(具有DVD和磁带的特定方法),它们继承自Player。 另外,如果你不需要DVD或磁带的特定方法,那么你不需要两个不同的接口只实现一个相同的方法 - 只需使用一个接口播放器,这就足够了。
答案 2 :(得分:2)
在这种情况下,没有问题,因为两个接口都有相同的方法签名。但是这个怎么样?
interface Animal {
public void eat() throws IOException;
}
interface Plants {
public void eat() throws NullPointerException;
}
编译器选择哪一个?为什么它会在代码下面出错?
public class Test implements Animal, Plants {
public void eat() throws IOException {
}
}
编译器说:异常IOException与Plants.eat()
中的throws子句不兼容答案 3 :(得分:1)
没有冲突,因为它们都指定了相同的契约,实现类只提供了通过任一接口引用时调用的一个方法。
答案 4 :(得分:1)
为什么不呢?该类满足两个接口定义的合同。
答案 5 :(得分:1)
该类实现了两个接口 - 所以没有问题。当然,在可能导致意外行为的更复杂场景中应该避免这种事情。
答案 6 :(得分:1)
以下页面包含一个类的示例 实现了两个具有
的接口1)相同的变量名称 2)每个界面中的方法相同。
http://www.j2eeonline.com/java-tm-fundamentals-II/module2/interface-ambiguous-fields.jsp