一. 引入默认接口方法的背景
java8可以看做是java版本更新迭代过程中变化最大的一个版本(与时俱进,方能不灭,我们应该感到欣慰),但是经过这么多年的发展和迭代,java的源码俨然已是一个庞然大物,要在这样庞大的体积上大动干戈,肯定不易。所以当第一次看到java8的默认接口方法的时候,我第一感觉就是这是java的设计人员在填自己之前挖的坑。
从前几篇的讲解中我们知道java8在现有的接口上添加了许多方法,比如List的sort(Comparator super E> c)方法。如果按照java8之前接口的设计思路,当给一个接口添加方法声明的时候,实现该接口的类都必须为该新添加的方法添加相应的实现。考虑兼容性,这样是不可取的,所以说这是一个坑,而新的特性又要求不得不为接口添加一些新的方法,为了兼得鱼和熊掌,java8的设计人员提出了默认接口方法的概念。
这样说来,默认接口方法似乎是为api的设计人员而开发的,离我们普通开发人员还有些距离,这样想有点图森破啦,虽然我们不用去设计jdk,但是我们在日常的开发过程中还是会有提供api给别的业务方调用的需求,当我们在更新我们api的时候,就可以采用默认方法来提供更加高级的功能,同时保持兼容性。
二. 默认接口方法的定义
默认接口方法的定义很简单,只要在接口的方法定义前添加一个default关键字即可,如下:
public interface A { /** * 默认方法定义 */ default void method() { System.out.println("This is a default method!"); } }
当我们这样定义一个默认方法之后,所有实现该接口的子类都间接持有了该方法。或者你会和我一样觉得接口和抽象类越来越像了,确实,不过它们之间还是有如下差别:
1. 一个类只能继承一个类,但是可以实现多个接口 2. 抽象类可以定义变量,而接口却不能
抽象除了解决了我们上面提及到的问题,还具有如下好处:
1. 对于一些不是每个子类都需要的方法,我们给它一个默认实现,从而避免我们在子类中对其无意义的实现(一般我们都会throw new UnsupportedException())2. 默认方法为java的多重继承提供了新的途径(虽然我们只能继承一个类,但是我们可以实现多个接口啊,现在接口也可以定义默认方法了)
三. 冲突及其解决方法
因为一个类可以实现多个接口,所以当一个类实现了多个接口,而这些接口中存在两个或两个以上方法签名相同的默认方法时就会产生冲突,java8定义如下三条原则来解决冲突:
1. 类或父类中显式声明的方法,其优先级高于所有的默认方法2. 如果1规则失效,则选择与当前类距离最近的具有具体实现的默认方法3. 如果2规则也失效,则需要显式指定接口
下面通过几个例子加以说明:
例1
public interface A { /** * 默认方法定义 */ default void method() { System.out.println("A's default method!"); } }public interface B extends A { /** * 默认方法定义 */ default void method() { System.out.println("B's default method!"); } }public class C implements A, B { public static void main(String[] args) { new C().method(); } }// 输出:B's default method!
此处因为接口B相对于A距离C更近,同时B的method是一个具体的默认实现,依据规则2,所以此处实际上调用的是接口B的默认方法
例2
public class D implements A { }public class C extends D implements A, B { public static void main(String[] args) { new C().method(); } }// 输出:B's default method!
例2在原有接口A、B的基础上,添加了一个实现接口A的类D,然后类C继承于D,并实现A和B,此处虽然C离D更近,但因为D的具体实现在A中,所以B中的默认方法还是距离最近的默认实现,依据规则2,此处实际上调用的是B的默认方法。
例3
// A接口不变public interface B { /** * 默认方法定义 */ default void method() { System.out.println("B's default method!"); } }public class C implements A, B { @Override public void method() { // 必须显式指定 B.super.method(); } public static void main(String[] args) { new C().method(); } }
例3中接口B不再继承自接口A,所以此时C中调用默认方法method()距离接口A和B的具体实现距离相同,编译器无法确定,所以报错,此时需要显式指定:B.super.method()。

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

ZendStudio 13.5.1 Mac
功能强大的PHP集成开发环境

PhpStorm Mac 版本
最新(2018.2.1 )专业的PHP集成开发工具

SecLists
SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。

DVWA
Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

VSCode Windows 64位 下载
微软推出的免费、功能强大的一款IDE编辑器