Java8是Oracle于2014年3月发布的一个重要版本,其API在现存的接口上引入了非常多的新方法。
例如,Java8的List接口新增了sort方法。在Java8之前,则每个实现了List接口的类必须定义sort方法的实现,或者从父类中继承它的实现。想象一下,如果List接口的继承体系非常庞杂,那么整个集合框架的维护量有多么大!
为此,在Java8中引入了一种新的机制:接口支持申明带实现的方法。
默认方法
前文提到了Java8中List接口新增了sort方法,其源码如下:
public interface List<E> extends Collection<E> {
// ...其他成员
default void sort(Comparator<? super E> c) {
...
...
}
}
可以看到,这个新增的sort方法有方法体,由default修饰符修饰,这就是接口的默认方法。
很显然,默认方法不是static的,所以必须由接口的实现类的实例来调用这些默认方法。
下面自定义一个接口,练习使用默认方法。
public interface Sized {
// 普通抽象方法,默认是public abstract修饰的,没有方法体
int size();
/*
* 默认方法,有方法体
* 任何一个实现了Sized接口的类都会向动继承isEmpty的实现
*/
default boolean isEmpty() {
return this.size() == 0;
}
}
其实,随着JDK版本的不断升级,API在不断演进,默认方法在Java8的API中已经大量地使用了,上面List接口中的sort方法就是其中一个。
和抽象类的区别
有同学可能发现了,Java8中加入了默认方法的接口,这不就是以前的抽象类吗?其实,两者还是有区别的。
解决冲突
我们知道Java语言中一个类只能继承一个父类,但是一个类可以实现多个接口。随着默认方法在Java8中的引入,有可能出现一个类继承了多个签名一样的方法。这种情况下,类会选择使用哪一个函数呢?
为解决这种多继承关系,Java8提供了下面三条规则:
让我们一起看几个例子 。
场景1:
public interface A {
default void hello() {
System.out.println("hello from A");
}
}
public interface B extends A {
default void hello() {
System.out.println("hello from B");
}
}
public class C implements A, B {
public static void main(String[] args) {
new C().hello();
}
}
如图1,是这个场景的UML图。
我们对照上面三条规则来看,类C中main()方法会输出什么?
场景2:
如果C像下面这样继承了D,会怎么样?
public class D implements A {
}
public class C extends D implements A, B {
public static void main(String[] args) {
new C().hello();
}
}
如图2,是这个场景的UML图。
同样,我们对照着三条规则来看:
场景3:
将上面的D稍作修改:
public class D implements A {
public void hello() {
System.out.println("hello from D");
}
}
结果又如何?
由于依据规则(1),父类中声明的方法具有更高的优先级,所以程序会打印输出”hello from D”。
场景4:
假设现在B不在继承A:
public interface A {
default void hello() {
System.out.println("hello from A");
}
}
public interface B {
default void hello() {
System.out.println("hello from B");
}
}
public class C implements A, B {
public static void main(String[] args) {
new C().hello();
}
}
如图3,是这个场景的UML图。
此时,由于编译器无法识别A还是B的实现更加具体,所以会抛出编译错误:”C inherits unrelated defaults for hello() from types A and B“。
像这种场景要解决冲突,可以在C中覆盖hello()方法并在方法内显示的选择调用A还是B的方法。
调用方式如下:
public class C extends D implements A, B {
public void hello() {
// 显式地选择调用接口B中的方法
// 同理,要调用接口A中的方法,可以这样:A.super.hello()
B.super.hello();
}
public static void main(String[] args) {
// 输出 hello from B
new C().hello();
}
}
场景5:
public interface A {
default void hello() {
System.out.println("hello from A");
}
}
public interface B extends A{
}
public interface C extends A{
}
public class D implements B, C {
public void hello() {
new D().hello();
}
}
此时,只有一个方法申明可以选择,所以程序会输出”hello from A”。
欢迎工作一到五年的Java工程师朋友们加入Java程序员开发: 721575865
群内提供免费的Java架构学习资料(里面有高可用、高并发、高性能及分布式、Jvm性能调优、Spring源码,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多个知识点的架构资料)合理利用自己每一分每一秒的时间来学习提升自己,不要再用”没有时间“来掩饰自己思想上的懒惰!趁年轻,使劲拼,给未来的自己一个交代!
很多朋友都在上找项目,有的朋友也被割过韭菜,因为做互联网的人没有谁是没被割过韭菜的,有的韭菜终有一天会茁壮成长,有的韭菜肯定会被无情的镰刀割到你怀疑人生。 韭菜就是被割的,你不割它会烂在地里。韭菜内心愤愤不平,继续辗转到下一块地再次茁壮生长,殊不知,山顶、山腰、山谷都可以割,而且镰刀更加锋利。...
1,568A网络电缆颜色顺序: 首先剥开网络电缆,然后从左到右排列顺序:白绿色,绿色,橙色,蓝色,白色蓝色,橙色,白色棕色和棕色。 2、568B网线颜色顺序: 剥开网络电缆并从左到右排列顺序:白色橙色,橙色,白色绿色,蓝色,白色蓝色,绿色,白色棕色,棕色。...
在淘宝上购物的次数多了之后难免会有需要换货的情况,因为现在很多店铺的规格太多了,一不小心就可能下错单,导致需要换货,很多人还不知道怎么去进行换货,下面说说淘宝换货的流程吧。我们如果 在淘宝上购物的次数多了之后难免会有需要换货的情况,因为现在很多店铺的规格太多了,一不小心就可能下错单,导致需要换货,...
搜索引擎是大家日常生活经常使用的工具,遇到不了解的事就搜一下,很方便。但有时候,如果根本不知道要搜索的东西是什么,就很难去搜索。对此,我们可以以图搜图,用图片去搜索,解决上述难题。 搜索引擎是大家日常生活经常使用的工具,遇到不了解的事就搜一下,很方便。但有时候,如果根本不知道要搜索的东西是什么,就...
7码鞋子是中国的多少码在男鞋中代表中国的四十一码,在女鞋中代表三十八码。鞋子的尺码在各个国家都不相同,例如澳大利亚、欧洲、墨西哥、日本以及英国等众多国家表示鞋子尺码的方式也是不同的 7码鞋子是中国的多少码 在男鞋中代表中国的四十一码,在女鞋中代表三十八码。鞋子的尺码在各个国家都不相同,例...
电商业内人都知道,现在平台方是“大甲方“,因为他们手里握有让品牌方趋之若鹜的流量资源包。这也就是为什么现在的品牌方会争相去PK上面说的这些超级品牌日、欢聚日活动,因为这些IP活动都 电商业内人都知道,现在平台方是“大甲方“,因为他们手里握有让品牌方趋之若鹜的流量资源包。这也就是为什么现在的品牌方会...
由于新冠肺炎,在家工作现在成为趋势。在家工作,也称为远程工作、远程办公、远程工作等,但远程工作并不是什么新鲜事。在家工作最早是在1979年发明的;作为一项实验,五名IBM员 由于新冠肺炎,在家工作现在成为趋势。在家工作,也称为远程工作、远程办公、远程工作等,但远程工作并不是什么新鲜事。在家工作最早...
NO.1Prada普拉达“潮流明星同款”普拉达于1913年成立于意大利米兰,其眼镜独特的时尚感、流行感成为许多明星装扮自己的标准配备。除了是一种时尚的表征,也是散发神秘魅力的利器,设计背后的生活哲学正巧契合现代人追求 NO.1 Prada普拉达“潮流明星同款” 普拉达于1913年成立于意大利...
2022年七月,八月,天气炎热,几乎每日都要开启“昼蒸夜煮”的模式,都躲在家里,吹着空调,看着电视,吃着西瓜,似乎成为了大多数人的宅家三部曲。转眼间,到了九月,气温下降了不少,但是当很多朋友收到七八月份电费账单的时候,心 2022年七月,八月,天气炎热,几乎每日都要开启“昼蒸夜煮”的模式,都躲在家...
羊血是比较少见的一种动物血液,它里面也含有丰富的营养成分,可以起到很不错的功效与作用,适量食用可以补血止血、祛瘀解毒等,补充人体所需的营养,但是服用不当,也可能会增加肠胃负担,引起消化不良以及肠胃不适。羊血的功效与作用及 羊血是比较少见的一种动物血液,它里面也含有丰富的营养成分,可以起到很不错的功...
板栗是秋季比较常见的一种美食,它的吃法比较多,吃起来软糯可口,营养价值高,深受人们喜欢。板栗一般要吃热的,这样比较容易消化吸收,冷掉的熟板栗可以放微波炉加热,一般只要是开口的板栗,短时间加热是不会爆炸的。板栗可以微波炉加 板栗是秋季比较常见的一种美食,它的吃法比较多,吃起来软糯可口,营养价值高,深...
薯片是很多人爱吃的零食,随着科技与狠活的流行,不少人都好奇薯片是不是属于海克斯科技系列,其实也属于的,薯片很多人都以为是马铃薯制作而成,其实并不是,而是由马铃薯全粉制作。薯片是科技与狠活吗市面上的薯片都属于再制薯片,并不 薯片是很多人爱吃的零食,随着科技与狠活的流行,不少人都好奇薯片是不是属于海克...
寒露节气是一年之中比较特别的一个节气,一般是在每年十月初,这个时候的气温会慢慢下降,大多数地区不会出现高温天气了,开始进入秋天。根据相关信息显示,今年寒露节气的温度大概是20度左右,北方在10度左右。2022寒露温度大约 寒露节气是一年之中比较特别的一个节气,一般是在每年十月初,这个时候的气温会慢...
远古海底最恐怖的生物 今天给大家盘点一下古代九大史前巨兽,它们凶猛、巨大、可怕。将近三米的大蜈蚣简直就是现代蜈蚣的祖先。 九大远古时代的史前巨兽? 还有一些大的残忍的野兽,看起来像现代的蝎子。为什么残忍?因为这种野兽因为吃了自己的肉而灭绝了!接下来是精彩时刻。请逐一阅读。 第九...
国庆节和中秋节都是生活中比较特别的两个节日,也是我国的法定节假日,它们都会放假休息,在2023年,中秋节是在9月29日,正好和国庆节凑到一起了,这样国庆节和中秋节可能会一起放假9天,也可能会放假8天,具体看相关放假安排通 国庆节和中秋节都是生活中比较特别的两个节日,也是我国的法定节假日,它们都会放...