按照理解,一般都是说Java 类是单继承,但可以实现多个接口。但是可以通过接口来实现类的多继承。(如何通过接口来实现多继承???)
那么就一直以为Java里面是单继承,今天看FutureTask源码的时候发现,接口居然可以实现多继承,通过下面例子学习下。
一个类只能extends一个父类,但可以implements多个接口。java通过使用接口的概念来取代C++中多继承。与此同时,一个接口则可以同时extends多个接口,却不能implements任何接口。因而,Java中的接口是支持多继承的。
下面先对接口做个总结:
1>接口中的成员变量默认都是public,static,final(都可省略),必须被显示初始化,即接口中的成员变量必须是常量。
2>接口中的方法默认都是public abstract类型的(都可省略),没有方法体。
3>接口中只能包含public abstract类型的成员方法和public static final类型的成员变量。
4>接口中没有构造方法,不能被实例化
5>一个接口不能实现(implements)另一个接口,但是可以多继承接口
6>Java中必须通过类来实现接口中的抽象方法
7>当类实现了某个Java接口时,它必须实现接口中的所有抽象方法,否则这个类必须声明为抽象类
8>不允许创建接口的实例(实例化),但允许定义接口类型的引用变量,该引用变量引用实现了这个接口的类的实例
9>一个类只能继承一个直接的父类,但可以实现多个接口,间接的实现了多继承
下面给一个接口多继承的例子,注意打印的a的值
1 package Lesson1218Thread; 2 3 public interface TestIFA { 4 int a = 0; 5 int b = 1; 6 int c = 2; 7 8 void printInfo(); 9 10 } 11 12 package Lesson1218Thread; 13 14 public interface TestIFB { 15 int a = 4; 16 int b = 5; 17 int c = 6 ; 18 19 void printInfo(); 20 } 21 22 package Lesson1218Thread; 23 24 public interface TestIFC extends TestIFA,TestIFB { 25 //int d = 4; 26 int a = 7; 27 } 28 29 package Lesson1218Thread; 30 31 public class IFDemo implements TestIFC{ 32 33 public static void main(String[] args) { 34 35 IFDemo ifdemo = new IFDemo(); 36 System.out.println("a is "+ifdemo.a); //a is 7, 因为这个地方实现接口TestIFC, 若是TestIFB, 则输出a is 4. 37 38 } 39 40 @Override 41 public void printInfo() { 42 System.out.println("which IF ?????"); 43 44 } 45 46 }
重点关注line36, 测试类实现哪个接口,输出的a就是哪个接口定义的值。
问题1:若同时实现两个接口,调用里面相同变量 , 编译错误。 如下:
1 package Lesson1218Thread; 2 3 public class IFDemo implements TestIFA,TestIFC{ //同时实现两个接口 4 5 public static void main(String[] args) { 6 7 IFDemo ifdemo = new IFDemo(); 8 System.out.println("a is "+ifdemo.a); //编译错误 9 10 } 11 12 @Override 13 public void printInfo() { 14 System.out.println("which IF ?????"); 15 16 } 17 18 }
line8 会报编译错误: The field ifdemo.a is ambiguous
程序不能找到应该调用哪个里面的a.
结论:接口多继承时,接口里面有定义相同的变量,如果实现类要调用相同变量,必须显示指出来。如 TestIFA.a 。
问题2:同时实现两个接口,若接口中的成员方法名字相同,但是返回值不一样,
1 package Lesson1218Thread; 2 3 public interface TestIFA { 4 int a = 0; 5 int b = 1; 6 int c = 2; 7 8 void printInfo(); 9 10 } 11 12 package Lesson1218Thread; 13 14 public interface TestIFB { 15 int a = 4; 16 int b = 5; 17 int c = 6 ; 18 19 String printInfo(); 20 } 21 22 package Lesson1218Thread; 23 24 public interface TestIFC extends TestIFA,TestIFB { //编译错误 25 //int d = 4; 26 int a = 7; 27 }
接口TestIFA中含有成员方法void printInfo(); 而接口TestIFB中含有成员方法String printInfo(); 两个成员方法返回值不一样。
接口TestIFC想继承上面两个类,编译错误。The return types are incompatible for the inherited methods TestIFA.printInfo(), TestIFB.printInfo()
结论:被多继承的接口中,不能有方法名相同,但是返回值不一样的函数。否则没法多继承。