Java8 新特性,打破你对接口的认知
Java 8 之前,接口里面只能写抽象方法,不能写实现方法
Java 8 开始是可以有方法实现的,可以在接口中添加默认方法和静态方法
默认方法用 default 修饰,只能用在接口中,静态方法用 static 修饰,并且接口中的默认方法、静态方法可以同时有多个。
为什么要用接口默认方法
举一个很现实的例子:
我们的接口老早就写好了,后面因为各种业务问题,避免不了要修改接口。
在 Java 8 之前,比如要在一个接口中添加一个抽象方法,那所有的接口实现类都要去实现这个方法,不然就会编译错误,
而某些实现类根本就不需要实现这个方法也被迫要写一个空实现,改动会非常大。
所以,接口默认方法就是为了解决这个问题,只要在一个接口添加了一个默认方法,所有的实现类就自动继承,不需要改动任何实现类,也不会影响业务;
另外,接口默认方法可以被接口实现类重写。
为什么要有接口静态方法?
接口静态方法和默认方法类似,只是接口静态方法不可以被接口实现类重写。
接口静态方法只可以直接通过静态方法所在的 接口名.静态方法名 来调用。
接口默认方法多继承冲突问题
因为接口默认方法可以被继承并重写,如果继承的多个接口都存在相同的默认方法,那就存在冲突问题。
冲突一
interface People {
default void eat() {
System.out.println("人吃饭。");
}
}
interface Man {
default void eat() {
System.out.println("男人吃饭。");
}
}
//Boy 同时继承了 People 和 Man,此时在 IDEA 编辑器中就会报错
interface Boy extends People, Man {
}
//这就是接口多继承带来的冲突问题,Boy 不知道该继承谁的,
//这显然也是个问题,IDEA 也会提示,需要重写这个方法才能解决问题:
interface Boy extends People, Man {
@Override
default void eat() {
People.super.eat(); //在方法里面还能直接调用指定父接口的默认方法
Man.super.eat(); //在方法里面还能直接调用指定父接口的默认方法
System.out.println("男孩吃饭。");
}
}
用实现类测试一下
class Student implements Boy {
public static void main(String[] args) {
Student student = new Student();
student.eat();
}
}
//result
//人吃饭。
//男人吃饭。
//男孩吃饭。
冲突二
我们再换一种写法,把 Man 继承 People,然后 Man 重写 People 中的默认方法
此时,编辑器不报错了,而 People 的默认方法置灰了,提示没有被用到。
再运行一下上面的示例,输出:
interface People {
default void eat() {
System.out.println("人吃饭。");
}
}
interface Man extends People{
default void eat() {
System.out.println("男人吃饭。");
}
}
interface Boy extends People, Man {
}
//result
//男人吃饭
因为 Man 继承 People,Man 又重定了默认方法。很显然,这个时候,Boy 知道该继承谁的默认方法了。
注意,此时,如果用 People 通过 super 调用父类的 eat 方法会报错,因为调不到了
interface Boy extends People, Man {
@Override
default void eat() {
People.super.eat(); //People报错
System.out.println("男孩吃饭");
}
}
冲突三
在 Man 接口中新增一个方法:say,然后在 Boy 接口中新增一个默认方法:say。
interface Man extends People{
default void eat() {
System.out.println("男人吃饭。");
}
void say(); //IDEA提示,say方法变灰,没有被使用
}
这时候,Man 中的抽象方法居然被忽略了,IDEA 都提示说没用到,这显然是默认方法优先于抽象方法。
总结
介绍了 Java 8 的默认方法和静态方法,以及默认方法的冲突问题解决方案。
如果以后还说接口不能写实现方法,那就太OUT了。
Java8 新特性,打破你对接口的认知的更多相关文章
- Java8新特性
Java8新特性 Java8主要的新特性涵盖:函数式接口.Lambda 表达式.集合的流式操作.注解的更新.安全性的增强.IO\NIO 的改进.完善的全球化功能等. 1.函数式接口 Java 8 引入 ...
- java8 新特性精心整理
前言 越来越多的项目已经使用 Java 8 了,毫无疑问,Java 8 是Java自Java 5(发布于2004年)之后的最重要的版本.这个版本包含语言.编译器.库.工具和 JVM 等方面的十多个新特 ...
- java8 新特性精心整理(全)
前言 越来越多的项目已经使用 Java 8 了,毫无疑问,Java 8 是Java自Java 5(发布于2004年)之后的最重要的版本.这个版本包含语言.编译器.库.工具和 JVM 等方面的十多个新特 ...
- Java8 新特性(三) - 日期时间对象以及一些其他特性
日期时间对象 关于日期时间的操作可以分为两种: 转换:与字符串的互相转换,与时间戳的互相转换 计算:计算两个时间点之间的间隔.时间点与时间段的计算(计算下周N.下个月D日.去年M月D日等等) Java ...
- 【Java8新特性】Lambda表达式基础语法,都在这儿了!!
写在前面 前面积极响应读者的需求,写了两篇Java新特性的文章.有小伙伴留言说:感觉Lambda表达式很强大啊!一行代码就能够搞定那么多功能!我想学习下Lambda表达式的语法,可以吗?我的回答是:没 ...
- Lambad表达式--Java8新特性
1.概述 Lambda是一个匿名函数,是java8的一个新特性.可以对接口进行非常简洁的实现.但它要求接口中只能有一个抽象方法,原因是lambda只能实现一个方法.另外,需要在接口上添加注解@Func ...
- java8新特性全面解析
在Java Code Geeks上有大量的关于Java 8 的教程了,像玩转Java 8--lambda与并发,Java 8 Date Time API 教程: LocalDateTime和在Java ...
- Java系列 - 用Java8新特性进行Java开发太爽了
本人博客文章网址:https://www.peretang.com/using-java8s-new-features-to-coding-is-awesome/ 前言 从开始写博客到现在已经过去3个 ...
- Java8 新特性之Stream----java.util.stream
这个包主要提供元素的streams函数操作,比如对collections的map,reduce. 例如: int sum = widgets.stream() .filter(b -> b.ge ...
- 这可能是史上最好的 Java8 新特性 Stream 流教程
本文翻译自 https://winterbe.com/posts/2014/07/31/java8-stream-tutorial-examples/ 作者: @Winterbe 欢迎关注个人微信公众 ...
随机推荐
- CTF--Do you like xml
题目链接:http://47.94.221.39:8008/ 扫描目录得到/.DS_Store文件 下载文件,直接用脚本进行还原操作. https://github.com/lijiejie/ds_s ...
- 【网鼎杯2020白虎组】Web WriteUp [picdown]
picdown 抓包发现存在文件包含漏洞: 在main.py下面暴露的flask的源代码 from flask import Flask, Response, render_template, req ...
- 论文解读(GMI)《Graph Representation Learning via Graphical Mutual Information Maximization》
Paper Information 论文作者:Zhen Peng.Wenbing Huang.Minnan Luo.Q. Zheng.Yu Rong.Tingyang Xu.Junzhou Huang ...
- 机械学习笔记1 -> Solidworks三维产品设计与建模1 | 建模基础入门
学习之余,课余了解一点点,作为爱好,妄想以后能够设计机甲出来. 学习来源是Solidworks三维产品设计与建模 00 工作界面介绍 00-1 概览 有时菜单栏和工具栏会重叠在一起,只有点击左侧三角才 ...
- 生命周期内create和mounted的区别?
created: 在模板渲染成html前调用,即通常初始化某些数据,然后再渲染成视图. mounted: 在模板渲染成html后调用,通常是初始化页面完成后,再对html的dom节点进行一些需要的操作 ...
- 如何在 Windows 和 Linux 上查找哪个线程使用的 CPU 时 间最长?
使用 jstack 找出消耗 CPU 最多的线程代码
- 详解 IOC
什么是IOC: IOC-Inversion Of Control,即"控制反转",不是什么技术,而是一种设计思想.在Java开发中,IOC意味着将你设计好的对象交给容器控制,而不是 ...
- 学习openstack(一)
一.云计算 云计算特点:必须通过网络使用:弹性计算(按需付费):对用户是透明的(用户不考虑后端的具体实现): 云计算分类:私有云.公有云(amazon是老大.aliyun.tingyun.tencen ...
- Java根路径设置(在获取本地路径时会获取到这个文件夹,,这样就可以专门放配置文件了)
在获取本地路径时会获取到这个文件夹,,这样就可以专门放配置文件了
- BMZCTF SDNISC2020_过去和现在
SDNISC2020_过去和现在 打开附件就一张图片 根据题意感觉是图片中隐藏了什么信息 使用binwalk -e分离这里foremost不行 三个文件查看在第一个中发现flag