2019年08月19日(星期一)  农历:己亥年七月十九

作者:三年。分类: JAVA

最近在读一些源码的时候突然发现了一个很神奇的东西,它的原始形态是这样的:

在这行代码中,BlockingDeque、BlockingQueue和Deque是三个接口。刚发现这个问题时,我是十分吃惊的,因为即使在《Thinking in Java》中也没有提到接口之间的继承。所以我立即把这个疑问提交到了stackoverflow上面。

正如在stackoverflow上面所讨论的一样,一个类只能extends一个父类,但可以implements多个接口。java通过使用接口的概念来取代C++中多继承。与此同时,一个接口则可以同时extends多个接口,却不能implements任何接口。因而,Java中的接口是支持多继承的。

然后我又做了个实验,来验证如果多个父子接口中有多个相同的方法声明,然后在实现这个最终的接口的时候,相同的方法声明在实现的时候会不会有冲突呢?

首先写了个接口:TestInterfaceA.java:

1 package com.peter.java.dsa.interfaces;

2

3 public interface TestInterfaceA {

4     String pri_key = "guess what the private key is";

5

6     int add(int x, int y);

7

8     String encryt(byte[] result);

9

10     int get();

11 }

注意,里面声明了三个方法和一个变量;

然后再与了一个接口:TestInterfaceB.java:

1 package com.peter.java.dsa.interfaces;

2

3 public interface TestInterfaceB {

4     String pub_key = "guess what the public key is";

5

6     int minus(int x, int y);

7

8     byte[] decryt(String src);

9

10     int get();

11 }

里面也声明了三个方法和一个变量;

然后再定义了一个接口InterfaceMultiInheritance.java同时继承了接口TestInterfaceA.java和接口TestInterfaceB.java:

1 package com.peter.java.dsa.interfaces;

2

3 public interface InterfaceMultiInheritance extends TestInterfaceA,

4         TestInterfaceB {

5     int num = 1024;

6

7     double divide(int x, int y);

8

9     int get();

10 }

里面声明了两个方法和一个变量;

注意,在这三个接口中,有一个共同的方法声明:get()。这个都是要讨论的主题。

最后在一个类InterfaceImplementTest.java中实现了接口InterfaceMultiInheritance.java,源码如下:

1 package com.peter.java.dsa.common;

2

3 import com.peter.java.dsa.interfaces.InterfaceMultiInheritance;

4 import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException;

5 import com.sun.org.apache.xml.internal.security.utils.Base64;

6

7 public class InterfaceImplementTest implements InterfaceMultiInheritance {

8

9     @Override

10     public int add(int x, int y) {

11         // TODO Auto-generated method stub

12         return x + y;

13     }

14

15     @Override

16     public String encryt(byte[] result) {

17         // TODO Auto-generated method stub

18         return Base64.encode(result);

19     }

20

21     @Override

22     public int minus(int x, int y) {

23         // TODO Auto-generated method stub

24         return x - y;

25     }

26

27     @Override

28     public byte[] decryt(String src) {

29         // TODO Auto-generated method stub

30         try {

31             return Base64.decode(src);

32         } catch (Base64DecodingException e) {

33             // TODO Auto-generated catch block

34             e.printStackTrace();

35         }

36         return null;

37     }

38

39     @Override

40     public double divide(int x, int y) {

41         // TODO Auto-generated method stub

42         return x/y;

43     }

44

45     @Override

46     public int get() {

47         // TODO Auto-generated method stub

48         return num;

49     }

50

51     public void print() {

52         System.out.println("The public key is: "+pub_key+"\nThe private key is: "+pri_key);

53     }

54

55 }

在这个类中,只有一个get方法实现了,同时也没有为有多个get要实现而冲突。同时,如果删除了接口InterfaceMultiInheritance.java中的get方法,也只有一个get方法得到了实现并且没有为多个get要实现而出现什么冲突。

所以,我们可以得到一个结论,当编译器在实现接口的时候会依然检查接口InterfaceMultiInheritance.java、 TestInterfaceA.java和TestInterfaceB.java中的方法声明,如果后两者有与前者相冲突的方法声明,编译器将只要求类 实现前者的声明,而后两者中相同的方法声明将自动被忽略。而当只有后两者中有相同的方法声明时,编译器将实现其中的一个即可。就好像是编译器中有一个专门存储方法声明的Set一样,在有继承关系的接口中,只保存一次相同的方法声明。

温馨提示如有转载或引用以上内容之必要,敬请将本文链接作为出处标注,谢谢合作!

已有 0/1431 人参与

发表评论:



手Q扫描加入Java初学者群