今天遇到一个问题,代码(后面各个版本的代码都是基于此代码进行变更的)如下:
public interface Type1 { void f(); void f1(); void f11(); }
public interface Type2 { void f(); void f2(); void f22(); }
public class IFTest implements Type1, Type2 { @Override public void f2() { } @Override public void f22() { } @Override public void f() { System.out.println("method f"); } @Override public void f1() { } @Override public void f11() { } }
当时有过这样一个疑问:Type1和Type2中都有一个f()方法,那么IFTest中的f()方法到底实现的是Type1中的f()呢,还是Type2中的f()呢?其实,这种疑问是多余的,因为IFTest中的f()既是Type1中的f()也是Type2中的f()。因为既然IFTest这个类没有发生编译错误,那就说明它既实现Type1也实现了Type2,也就是说Type1中的f()与Type2中的f()在IFTest中是相安无事的。可以通过以下的JUnit测试用例来看一下:
public class IFTestTest { /** * Test method for {@link com.rainbow.util.demo.iftest.IFTest#f()}. * * @throws IOException */ @Test public void testF() throws Exception { Type1 ift = new IFTest(); Type2 ift2 = new IFTest(); ift.f(); ift2.f(); } }
它的打印结果中是:
method f method f
-------------------------------------------分隔线-------------------------------------------
上面这个问题的变种:
将Type1中的f()的返回值修改为int,将Type2中的f()的返回值修改为boolean,那么又会是什么结果呢?
public interface Type1 { int f(); void f1(); void f11(); }
public interface Type2 { boolean f(); void f2(); void f22(); }
public class IFTest implements Type1, Type2 { @Override public void f2() { } @Override public void f22() { } @Override public void f() { System.out.println("method f"); } @Override public void f1() { } @Override public void f11() { } }
在我意料之中,此时IFTest这个类在编译时就报错了, 在Eclipse中,将鼠标移至IFTest的f()上,查看一下,出错消息为:
The return type is incompatible with Type2.f()
这也就说明了,如果两个接口有同名的方法,但是它们的返回值不一样,那么,是无法用一个类同时来实现这两个接口的。
-------------------------------------------分隔线-------------------------------------------
上面这个问题的变种:
将Type1中的f()声明为抛出IOException,将Type2中的f()声明为抛出CloneNotSupportedException,那么又会是什么结果呢?
public interface Type1 { void f() throws IOException; void f1(); void f11(); }
public interface Type2 { void f() throws CloneNotSupportedException; void f2(); void f22(); }
public class IFTest implements Type1, Type2 { @Override public void f2() { } @Override public void f22() { } @Override public void f() throws CloneNotSupportedException, IOException { System.out.println("method f"); } @Override public void f1() { } @Override public void f11() { } }
我本来以为上面的IFTest是可以正常通过编译的。但是,结果却是残酷的,在Eclipse中可以查看到出错消息为:
Exception IOException is not compatible with throws clause in Type2.f()
对于这个现象,在《Java 解惑》的迷题37中,有如下的描述:
一个方法可以抛出的受检查异常集合是它所适用的所有类型的声明要抛出的受检查异常集合的交集,而不是合集。
也就是说,在IFTest的f()上声明的异常只能是在Type1和Type2的f()上都声明过的异常。因为此示例中,Type1抛出的是IOException,而Type2抛出的是CloneNotSupportedException,即Type1与Type2的f()所抛出的异常是没有交集的,因此,IFTest的f()是无法声明抛出任何异常的。
如果像下面这样修改一下:
public interface Type1 { void f() throws IOException, CloneNotSupportedException; void f1(); void f11(); }
public interface Type2 { void f() throws CloneNotSupportedException; void f2(); void f22(); }
那么,就可以将IFTest的f()修改为声明抛出 ClonseNotSupportedException了,因为这个时候Type1和Type2的f()都声明了 ClonseNotSupportedException,这个异常就是它们抛出的异常的交集:
public class IFTest implements Type1, Type2 { @Override public void f2() { } @Override public void f22() { } @Override public void f() throws CloneNotSupportedException { System.out.println("method f"); } @Override public void f1() { } @Override public void f11() { } }
当然,对于这一点,一定要注意一下,仅仅是针对 受检查的异常(Checked Exception) 才起作用的,对于非受检查的异常(Unchecked Exception)则不适用。
关于什么是 Checked Exception ,什么是 Unchecked Exception,可以查看http://czj4451.iteye.com/blog/1851825
相关推荐
/**一个类实现了两个接口,两个接口中的方法相同,这个类在覆写的时候就会出现冲突*/ class D: B,C{ //当下面两个方法同时存在的时候,就会报方法相同的冲突 override fun x(): Int { return super
对于一个类实现两个接口,而这两个接口又有同名方法,C#中的处理方式如下: using System; using System.Collections.Generic; using System.Text; namespace Super { class Program { static void Main(string[] ...
方法的重载:在同一个类中定义多个同名的不同形态方法; 方法的覆盖:在子类中对父类定义方法的重新定义,在子类中将隐藏来自父类的同形态方法。 4-3 Java类的继承有何特点?如何理解接口的作用? 继承是存在于面向...
(3) 一个类虽只实现了一个接口,但不仅要实现这个接口的所有方法,还要实现这个接口 继承的接口的方法,接口中的所有方法均须在类中实现。 9、 接口的嵌入 (1) 接口嵌入类中,可以使用private修饰。此时,接口...
给定一个C语言函数,要求实现在java类中进行调用。 45.如何获得数组的长度? 46.访问修饰符“public/private/protected/缺省的修饰符”的使用 47.用关键字final修饰一个类或者方法时,有何意义? 48.掌握类和...
如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。 15、error和exception有什么区别? error 表示恢复不是...
一、判断题(每题1分,共15分) 1、Java允许创建不规则数组,即Java多维数组中各行的列数可以不同。...4、如果有两个类A、B(注意不是接口),你想同时使用这两个类的功能,那么你会如何编写这个C类呢? ........
如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。 18、error和exception有什么区别? error 表示恢复...
组合复用:选取某个类型中的一个对象的方法实现作为该类的方法实现过程,这两个类也称为理论父类和理论子类. 程序中是不出现extends关键字对两个类关系的描述的. 通过具体实例抽象出父类的过程称为泛化 通过...
如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。 15、error和exception有什么区别? error 表示恢复...
当客户端发出请求时,Servlet引擎传递给Servlet一个ServletRequest对象和一个ServletResponse对象,这两个对象作为参数传递到service()方法中。 Servlet也可以执行ServletRequest接口和ServletResponse接口。...
下例定义了一个 Point 类 ,并且声明了它的两个变量 x、y 坐标 ,同时实现 init()方法 对 x、y 赋初值 。 class Ponit { int x,y; void init(int ix, int iy){ x=ix; y=iy; } } 类中所定义的变量和方法都是类的...
B) 抽象类中的方法如果可以有实现体,如果没有实现体,则该方法叫做抽象方法必须加关键字abstract修饰该方法。 C) 抽象类中至少需要有一个方法被定义为抽象方法,在该方法前加abstract,把该方法定义为抽象方法。 D)...
PaintedPoint.java 实现了多个接口的方法 Point.java 一个简单的类 PrintColors.java 一个子接口 RainbowColors.java 一个子接口 realPoint.java 一个子类 second.java 属于一个命名包的类 showDiff.java ...
抽象包括两个方面,一是过程抽象,二是数据抽象。 2.继承: 继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法。对象的一个新类可以从现有的类中派生,这个过程称为类继承...
JAVA平台提供了两个类:String和StringBuffer,它们可以储存和操作字符串,即包含多个字符的字符数据。这个String类提供了数值不可改变的字符串。而这个StringBuffer类提供的字符串进行修改。当你知道字符数据要改变...
抽象包括两个方面,一是过程抽象,二是数据抽象 继承 是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确的表述共性的方法 对象的一个新类可以从现有的类中派生,这个过程称为类继承,新类...
答:多线程有两种实现方法,一种是继承Thread类或者实现Runnable接口。同步就是在方法返回类型后面加上synchronized。 c#中的委托,事件是不是委托? 答:委托就是将方法作为一个参数带入另一个方法叫做委托,事件...