作者 | 小明菜市场

来源 | 小明菜市场(ID:fileGeek)

头图 |  CSDN 下载自东方IC

前言

从一道面试题说起

A:接口里可以写方法吗?

B:可以的,默认就是抽象方法。

A:那接口里可以写实现方法吗?

B:不可以,所有的方法必须是抽象的。

A:你确定?

B:确定。。。。

好吧。这的的确确让人有点怀疑,所以本文就从这开始着手,

这里介绍一个Java8的新特性,接口增强

静态方法和默认方法

我们可以在Comparator接口的源码中,看到大量类似下面这样的方法声明。

//default关键字修饰的默认方法default Comparator<T> thenComparingInt(ToIntFunction<? super T> keyExtractor) {return thenComparing(comparingInt(keyExtractor));}//Comparator接口中的静态方法public static <T extends Comparable<? super T>> Comparator<T> naturalOrder() {return (Comparator<T>) Comparators.NaturalOrderComparator.INSTANCE;}

其中thenComparingInt()就是一个默认方法,它使用 default 关键字修饰。这是Java8引入的新功能,接口中的可以声明默认方法和静态方法。

默认方法带来的多继承问题

在此之前,Java中的类只支持多重继承,不支持多继承,现在有了默认方法,你可以以另外一种方式实现类的多继承行为,即,一个类实现多个接口,而这几个接口都有声明自己的默认方法。

这里面引发了一个多继承问题,设想一下,假如一个类从多个接口中继承了它们声明的默认方法,而这几个默认方法使用的都是相同的函数签名,那么程序运行时,类会选择调用哪个方法。

第一份代码

@Testpublic void test2() {new C().hello();//result: hello from D}interface A {default void hello() {System.out.println("heelo from A");}}interface B extends A {default void hello() {System.out.println("heelo from B");}}class D implements A{public void hello() {System.out.println("hello from D");}}class C extends D implements A, B{}

这份代码输出的结果是 hello from D,可以看到 C 类的父类D,父接口A,父接口B都定义了一个相同函数签名的hello(),最后实际调用的是父类D中声明的方法。

第二份代码

 @Testpublic void test4() {new I().hello();//result: heelo from G}class I implements G, H { }interface G extends E {default void hello() {System.out.println("heelo from G");}}interface H extends E { }interface E {default void hello() {System.out.println("heelo from E");}}

代码清单二的输出结果是 hello from G,可以看到 I 类的父接口 G,父接口E都定义了一个相同函数签名 hello(),最后实际调用的是父类接口G中声明的方法。

第三份代码

 @Testpublic void test3() {new F().hello(); //result: heelo from E}interface A {default void hello() {System.out.println("heelo from A");}}interface E {default void hello() {System.out.println("heelo from E");}}class F implements A, E {public void hello() {//这里接口A和E不再具有继承关系,需显式的选择调用接口E或A中的方法,否则无法通过编译E.super.hello();}}

第三份代码,类F必须显式的覆盖父接口的hello方法,否则无法通过编译器的检测,因为编译器无法确定父接口A和父接口E中的默认方法哪一个优先。这种情况下,如果你想调用某个父接口的默认方法,可以使用 接口名.super.默认方法名这种方式进行调用。

总结

Java8的新特性:接口中可以声明默认方法和静态方法。另外,接口默认方法带来的多继承问题,即,如果一个类使用相同的函数签名从多个地方继承了方法,通过这三种规则可以判断:

  1. 类中的方法优先级最高。类或父类中声明的方法的优先级高于任何声明为默认方法的优先级。

  2. 如果无法依据第一条进行判断,那么子接口的优先级更高:函数签名相同时,优先选择有最具体实现的默认方法的接口,即如果B继承了A,那么B就比A更加具体。

  3. 最后, 如果还是无法判断, 继承了多个接口的类必须通过显式覆盖和调用期望的方法, 显式地选择使用哪一个默认方法的实现(调用语法:  接口名.super.默认方法名 )。

Java 8 的这个新特性,用起来真的很爽!相关推荐

  1. Java 11 正式发布,新特性解读

    Java 11 正式发布,新特性解读 杨晓峰   2018 年 9 月 26 日 话题:Java语言 & 开发 不知不觉 JDK 11 已经发布了,从 9 开始,JDK 进入了让人学不动的更新 ...

  2. java的发展(8-17新特性整理)

    java java的诞生与历史: 简介:Java是一门面向对象的编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承.指针等概念,因此Java语言具有功能强大和简单易用两个特征. ...

  3. Java基础之Java8 新特性

    hp实训8.19_Java基础之Java8新特性 // 信息展示方法 ,接口中,就可以提供一种实现. 就可以使用这种功能.default void print() {System.out.printl ...

  4. 不停歇的Java即将发布JDK16新特性速览及从菜鸟到架构师[图]

    一.不停歇的Java即将发布JDK16新特性速览 当开发者深陷Java8版本之际,这边下一版本Java16有了最新的消息,与Java15一样,作为短期版本,Oracle仅提供6个月的支持. 根据发布计 ...

  5. 【JAVA拾遗】Java8新特性合辑

    [JAVA拾遗]Java8新特性合辑 文章目录 [JAVA拾遗]Java8新特性合辑 0. 逼逼 [--/--]126 Lambda Expressions & Virtual Extensi ...

  6. 详解 Java 17中的新特性:“密封类”

    作者:程序猿DD 博客:https://blog.didispace.com/ Java 17推出的新特性Sealed Classes经历了2个Preview版本(JDK 15中的JEP 360.JD ...

  7. Java 17 版本的新特性

    Java 17 版本的新特性

  8. 详解Java 8十大新特性

    前言: Java 8 已经发布很久了,很多报道表明Java 8 是一次重大的版本升级.在Java Code Geeks上已经有很多介绍Java 8新特性的文章,例如Playing with Java ...

  9. Java系列 – 用Java8新特性进行Java开发太爽了(续)

    本人博客文章网址:https://www.peretang.com/using-java8s-new-features-to-coding-is-awesome-2/ 前言 上周, 我们谈论了关于Ja ...

  10. Java 11正式发布,新特性解读

    不知不觉 JDK 11 已经发布了,从 9 开始,JDK 进入了让人学不动的更新节奏,对于广大 Java 工程师来说,真是又爱又恨,Java 演进快速意味着它仍将能够保持企业核心技术平台的地位,我们对 ...

最新文章

  1. mysql中Invalid default value for 'stime'问题
  2. mysql 关于日期时间的字段类型
  3. SQL Server资源管理之内存管理篇(上)
  4. ie6常见css bug
  5. mysql建表2个索引是啥意思_Mysql建表与索引使用规范详解
  6. 精通init ramfs构建
  7. linux系统中 库分为静态库和,Linux系统中“动态库”和“静态库”那点事儿-【经典好文】...
  8. 西瓜书——极大似然估计和朴素贝叶斯
  9. 在服务器托管中asp***的防范注意些什么?
  10. finalize方法注意事项(防止子类没有显示调用super.finalize())
  11. echo输出不重复行到文件 shell_Shell脚本echo指令使用小技巧
  12. Android-NDK 接入Fmod库,变声操作
  13. 真的会有大牛市吗老大?前提条件是破2万美刀,差一刀都不行!
  14. 百度地图大头针图片的自定义
  15. 崩坏3区号+86_手机号码前的“+86”是什么意思?
  16. Linux的基础存储管理
  17. 信息技术重返MBA课程
  18. 尚硅谷谷粒学院学习笔记(防坑点的总结部分勘误)
  19. 单片机ADC0832电压检测程序(充电自动提醒)
  20. 基于JAVA保险公司风险测评管理系统计算机毕业设计源码+系统+lw文档+部署

热门文章

  1. IT职场人生系列之二十:危险职业(下)
  2. (转载)JavaWeb学习总结(五十二)——使用JavaMail创建邮件和发送邮件
  3. [论文阅读] Tokens-to-Token ViT: Training Vision Transformers from Scratch on ImageNet
  4. 论文阅读:BPFINet: Boundary-aware progressive feature integration network for salient object detection
  5. Python程序设计学习笔记-语句与格式化输出
  6. 关于主函数main(int argc,char *argv[])
  7. 211计算机建设,“211工程”重点学科信息资源建设综述
  8. pytorch的图像通道变换,torchvision.transforms.Compose,T.ToTensor
  9. ip转换器哪个好用_中英文翻译软件哪个好?试试这两个就知道了
  10. 【OpenCV】读取显示图片及Mat类