【java基础】为什么子接口要覆盖父接口的方法
背景
研究java api1 – Queue时,对好奇的地方扩展阅读。发现Deque方法列表里有contains(),下方的继承于Collection的方法只是列出,产生疑问,contains()方法在Collection里也有,为啥子接口要重写父接口的方法呢?
研究
谷歌搜索"Why do some interfaces override the methods of the parent interface in java",找到两篇文章23,结合jdk源码看了下。
总结
文章3说明子接口覆盖父接口的方法的原因可能是java doc不同、抛出的运行时异常不同等等。接口在英文文档中常以contract表示,即一种契约,如果契约的说明不同,重写契约是有必要的,这是一种理解方式。
可以在源码中看到Deque接口的contains()、size()方法与Collection接口的这两个方法在运行时异常的说明上是一致的,在java doc上略有不同的地方也仅是将collection替换为deque。可以认为这样更精确,但为什么containsAll()不也这样做呢?实际上Deque并未覆盖containsAll。
查看LinkedBlockingDeque源码发现其继承了AbstractCollection,在AbstractCollection类文件里搜"contains("或"size("会发现有多处。读过Effective Java第18条复合优于继承的人,应该对add和addAll印象深刻,后者会依赖前者。所以我认为除了java doc说明不同需要覆盖的原因,最主要的还是这些接口是父类的最基本的接口,覆盖以突出,以便以后有需要时自定义实现。
可以参考List相关接口和实现类来对比,发现List覆盖了Collection更多方法,isEmpty()也覆盖了,而Deque是没有覆盖的。实际上AbstractQueue和AbstractList使用的都是AbstractCollection的isEmpty()方法。所以是否覆盖,可能还取决于是否希望子接口拥有更独立的自定义能力的可能性。
额外收获
文章2让我清楚了实例方法始终调用的是子类的,静态方法调用的是定义时左边声明的类的类型的(或者是强转后的类型的)。
javase tutorial值得一读。
https://docs.oracle.com/javase/8/docs/api/ Deque部分 ↩︎
https://docs.oracle.com/javase/tutorial/java/IandI/override.html ↩︎ ↩︎
https://softwareengineering.stackexchange.com/questions/315228/why-would-an-interface-override-methods-of-the-interfaces-it-extends-in-java-7 ↩︎ ↩︎
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
