话不多说,看代码
假设两个接口分别为Interface A1和Interface A2,实现类为 a
接口一
public interface A1 {
void f();
}
接口二
public interface A2 {
void f();
}
实现类
public class a implements A1, A2 {
@Override
public void f() {
System.out.println("fff");
}
}
当时有个疑问:如果两个不同接口中的方法名称相同,使用一个实现类同时实现两个接口,那么实现类中实现的方法是哪个接口中的呢?
其实,这种疑问是多余的,因为a中的f()既是A1中的f()也是A2中的f()。因为既然a这个类没有发生编译错误,那就说明它既实现A1也实现了A2,也就是说A1中的f()与A2中的f()在实现类a中是相安无事的。通过JUnit测试:
public class TestInterface {
@Test
public void testF() {
A1 a1 = new a();
A2 a2 = new a();
a1.f();
a2.f();
}
}
打印结果:
fff
fff
将接口的方法变更一下,接口中的方法名称相同,但是返回类型不同,结果会怎样呢?
接口一
public interface A1 {
int f();
}
接口二
public interface A2 {
void f();
}
实现类
public class a implements A1, A2 {
@Override
public void f() {
System.out.println("fff");
}
}
此时在IDE上面就会报错,在idea中报错
也就是说,多个接口中的方法名称相同,但是返回类型不同,不能使用一个实现类同时实现两个接口。
解决方法:实现类里面使用内部类,分别实现两个接口。
继续变更
接口一
public interface A1 {
int f()throws IOException;
}
接口二
public interface A2 {
void f()throws CloneNotSupportedException;
}
实现类
public class a implements A1, A2 {
@Override
public void f() throws IOException, CloneNotSupportedException{
System.out.println("fff");
}
}
此时IDE依然报错,报错内容如下
对于这个现象,在《Java 解惑》有所解释:
一个方法可以抛出的受检查异常集合是它所适用的所有类型的声明要抛出的受检查异常集合的交集,而不是合集。
也就是说,在a的f()上声明的异常只能是在A1和A2的f()上都声明过的异常。因为此示例中,A1抛出的是IOException,而A2抛出的是CloneNotSupportedException,即A1与A2的f()所抛出的异常是没有交集的,因此,a的f()是无法声明抛出任何异常的。
可以将上面的代码修改为:
接口一
public interface A1 {
int f()throws IOException,CloneNotSupportedException;
}
接口二
public interface A2 {
void f()throws CloneNotSupportedException;
}
实现类
public class a implements A1, A2 {
@Override
public void f() throws CloneNotSupportedException{
System.out.println("fff");
}
}
这样不会报错因为这个时候A1和A2的f()都声明了 ClonseNotSupportedException,这个异常就是它们抛出的异常的交集.当然对于这一点,需要注意的是,仅仅是针对受检查的异常(Checked Exception) 才起作用的,对于非受检查的异常(Unchecked Exception)则不适用。