4

假设你有两个接口 I1 和 I2 两个接口都有相同的方法

1)public int add(int a) throws exception e1    //(Interface 1)

2)public int add(int a) throws exception e2    //(Interface 2)

现在一个类同时实现了 I1 和 I2。

@override
public int add(int a) exception e1
{
//adding operation
}

注意:我知道如果您实现多个具有相同方法的接口,那么实现类中将只有一个实现。

  1. 编译器是否根据 throws 子句推断此方法是来自 I1 还是来自 I2?是否需要方法签名说明?(我知道签名包括名称和传递的参数。)

  2. 如果我们已经实现了这两个接口,然后我们只抛出 e1 ,编译器是否会允许这样做,因为实现类并没有真正实现这两个接口?会不会导致钻石结构问题?

  3. 我们是否需要使用 throws 子句 e1 和第二次 e2 实现相同的方法?当我尝试这个时,编译器告诉我我有重复的方法。

  4. 如果我们先实现 I1,那么它说它是 I1 的方法,如果我们先写 I2,那么它说它是 I2 的方法。解释为什么会这样。

4

2 回答 2

7

一个接口定义了一个契约。如果一个接口定义了一个方法

void foo() throws SomeException;

然后它说:所有实现类都必须有一个方法 foo,返回 void,不带任何参数,并且允许抛出 SomeException但不允许抛出其他类型的检查异常

实现方法当然可以选择根本不抛出任何异常,因为它不会违反接口方法的约定。throws意思是:这个方法在某些情况下可能会抛出这个异常。

因此,声明为的方法

public void foo();

在实现类中对上面定义的接口有效。

所以,在你的例子中,

public int add(int a) throws Exception1

是要覆盖的有效方法声明

int add(int a) throws Exception1

不适用于

int add(int a) throws Exception2

(当然除非 Exception1 是 Exception2 的子类)。

如果 Excption1 和 Exception2 之间没有继承,实现这两个接口的唯一方法是拥有一个不引发任何异常的方法。这是履行这两个合同的唯一可能性。

于 2013-11-12T15:47:07.400 回答
1

关于覆盖,只考虑方法的参数类型(8.4.2);稍后在单独的步骤(8.4.8.3)中检查返回类型和抛出类型。

一个类可以继承多个具有重写等效签名的方法。(8.4.8.4)那里没有问题。在您的情况下,继承了两种方法,然后都被一种方法覆盖。

我的 IDE IntelliJ 正确报告该方法覆盖了两个超级接口中的两个方法。

在 Java 7 及更早版本中,不存在菱形问题。但是,从 Java 8 开始,接口方法可以有实现!因此,当一个类从两个接口继承两个方法时,就会出现菱形问题。如果存在这种歧义,Javac 可能会拒绝该代码。(有办法消除歧义)。

于 2013-11-12T16:33:51.470 回答