概述

最近在看JDK集合的源码时,在Collection接口中发现了default关键字,并且惊奇的发现接口中的方法居然包含方法体,这顿时让我产生兴趣,为此我也稍微研究了一下default关键字。

很多同学都知道Java在创立之初就摒弃了C++多继承的套路,因为它实在难以学习与使用,在Java的世界中类只能继承一个父类,但是一个接口可以继承多个接口,就比如这样:

public interface A {
void hello();
} public interface B {
void hello();
} public interface C extends A,B { }

但是Java8的新特性也使得Java也拥有了多继承的问题,想要了解的小伙伴就继续往下看吧。

引入default关键字

大家都知道Java中的接口都是抽象方法,也就是没有方法体,但是从Java8开始,如果接口中的方法被default关键字修饰后就必须为其加上方法体。某个类在实现该接口时,就不会强制实现被default修饰的方法,因为在接口中已经写好了方法体。从Java8开始,接口就开始类似于抽象类了,它们都可以含有普通方法和抽象方法了,唯一不同的就是一个类只能继承一个抽象类,而一个类却能实现多个接口。

default关键字示例:

public interface A {
default void sayHello(){
System.out.print("A.Hello");
}
}

default关键字的意义:default关键字的意义,default的意思就是为接口方法提供默认的实现,它的最终目的就是减少子类实现接口的工作量,如果多个子类实现的某个接口方法,方法体都是一样的,这就会导致后期维护上的困难,如果在接口中定义默认的实现,那么既减少了子类实现的接口的工作量,也为后期的维护提供了方便(只需要更改接口中的默认实现即可)。

多继承问题的引入

但是default关键字的出现也顺带为java带来了多继承的问题,我现在来举一个栗子:

现有两个接口,A和B,这两个接口都有一个方法sayHello,并且都使用default关键字修饰后使其拥有了方法体,但是现在有接口C需要同时继承A,B,代码如下:

public interface A {
default void sayHello(){
System.out.print("A.Hello");
}
} public interface B {
default void sayHello(){
System.out.print("B.Hello");
}
} public interface C extends A,B{ }

此时多继承的问题就展现出来了,到底C接口是继承A接口的sayHello方法,还是继承B接口的sayHello方法,这也就是Java多继承的源头,允许接口有方法体,并且接口之间可以多继承。(上面代码由于有多继承问题,编译会报错!!)

多继承问题的解决

Java给出的解决方案就是:在出现多继承问题的时候必须手动覆写冲突方法,这种方式可谓是简单出爆,但很好理解。手动覆写后编译器就不纠结到底继承哪个父类的方法了,也就解决了多继承问题。

子接口在手动覆写父接口方法时可以手动调用冲突方法,调用格式如下:

public interface A {
default void sayHello(){
System.out.print("A.Hello");
}
} public interface B {
default void sayHello(){
System.out.print("B.Hello");
}
} public interface C extends A,B{
@Override
default void sayHello() {
A.super.sayHello();
}
}
public class Test impements A.B {//类的多实现本质上就是多继承
@Override
default void sayHello() {//因为接口A和接口B中的默认方法冲突,所以必须手动实现sayHello方法
A.super.sayHello();
}
}

另一种多继承

public interface A {
default void sayHello(){
System.out.print("A.Hello");
}
} public interface B extends A{
default void sayHello(){
System.out.print("B.Hello");
}
} public class Test impements A.B { }

在上述代码中,接口B继承了接口A,如果Test类实现A,B接口是不存在冲突的,实际上在实际开发中通常也不会这个写,因为既然B继承了A接口,那么在实现的时候直接实现B接口就行了,显示实现A接口没有任何意义。

拓展:Java8的接口可以拥有静态方法

可以参考博主另一篇文章:《Java8新特性——接口静态方法》

走过路过不要错过,原创不易,帮忙点个赞撒!!!!

Java8新特性default关键字,引出Java多继承问题的更多相关文章

  1. Java8 新特性default

    在JDK1.8的Iterator接口中 package java.util; import java.util.function.Consumer; public interface Iterator ...

  2. Java基础之java8新特性(1)Lambda

    一.接口的默认方法.static方法.default方法. 1.接口的默认方法 在Java8之前,Java中接口里面的默认方法都是public abstract 修饰的抽象方法,抽象方法并没有方法实体 ...

  3. 【Java】Java8新特性

    文章目录 Java8新特性 Lambda表达式的使用 语法格式一:无参,无返回值 语法格式二:Lambda 需要一个参数,但是没有返回值. 语法格式三:数据类型可以省略,因为可由编译器推断得出,称为& ...

  4. Java8新特性(一)_interface中的static方法和default方法

    什么要单独写个Java8新特性,一个原因是我目前所在的公司用的是jdk8,并且框架中用了大量的Java8的新特性,如上篇文章写到的stream方法进行过滤map集合.stream方法就是接口Colle ...

  5. 【Java基础】Java8 新特性

    Java8 新特性 Lambda 表达式 Lambda 是一个匿名函数,我们可以把 Lambda 表达式理解为是一段可以传递的代码(将代码像数据一样进行传递).使用它可以写出更简洁.更灵活的代码. L ...

  6. Java系列 - 用Java8新特性进行Java开发太爽了

    本人博客文章网址:https://www.peretang.com/using-java8s-new-features-to-coding-is-awesome/ 前言 从开始写博客到现在已经过去3个 ...

  7. java8新特性全面解析

    在Java Code Geeks上有大量的关于Java 8 的教程了,像玩转Java 8--lambda与并发,Java 8 Date Time API 教程: LocalDateTime和在Java ...

  8. Java8新特性【转】

    地址:http://ifeve.com/java-8-features-tutorial/ 1.简介 毫无疑问,Java 8是自Java  5(2004年)发布以来Java语言最大的一次版本升级,Ja ...

  9. Java8新特性

    Java8新特性 Java8主要的新特性涵盖:函数式接口.Lambda 表达式.集合的流式操作.注解的更新.安全性的增强.IO\NIO 的改进.完善的全球化功能等. 1.函数式接口 Java 8 引入 ...

  10. 干货 | Java8 新特性教程

    本教程翻译整理自 https://github.com/winterbe/java8-tutorial 本教程首发自个人网站: https://www.exception.site/java8/jav ...

随机推荐

  1. 分布式文件存储-FastDFS

    1.1 FastDFS简介 1.1.1 FastDFS体系结构 FastDFS是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储.文件同步.文件访问(文件上传.文件下载)等,解决了 ...

  2. ABP -Vnext框架一步一步入门落地教程——使用ABP -Vnext创建一个WEBAPI接口(二)

    开发主题:何谓开发应用服务端 在官方开发教程这一段的内容叫做开发应用服务端,作为现在前后端分离的开发模式来说,一个应用就分为前端页面框架和后端API,页面框架调用WEBAPI实现业务就完事了.所以咱们 ...

  3. 力扣367(java&python)-有效的完全平方数(简单)

    题目: 给定一个 正整数 num ,编写一个函数,如果 num 是一个完全平方数,则返回 true ,否则返回 false . 进阶:不要 使用任何内置的库函数,如  sqrt . 示例 1: 输入: ...

  4. GaussDB SQL查询语句执行过程解析

    本文分享自华为云社区<[GaussTech第2期]GaussDB SQL查询语句执行过程解析>,作者: GaussDB 数据库. SQL于关系型数据库而言,重要性不言而喻.就像一个乐团的指 ...

  5. 码住!Flink Contributor 速成指南

    简介: 不管初衷是什么,Flink 都非常欢迎大家一起建设和完善社区.在开始具体的贡献步骤之前,我们先简要介绍一下参与贡献的几种途径,以及 Clarify 关于开源贡献的一些固有印象. 作者:伍翀(云 ...

  6. 拒绝双写:巧用Lindorm数据订阅

    ​简介: 本文介绍了双写场景的一致性问题,详细介绍了三种解决方案,并针对DB->Binlog->Kafka方案给出了Lindorm数据订阅的最佳实践 双写问题介绍 双写问题(Dual Wr ...

  7. dotnet 使用 TaskTupleAwaiter 同时等待多个任务简化代码写法

    在某些业务逻辑下,需要同时等待多个任务执行完成,才能继续往下执行后续逻辑.等待任务执行的逻辑,大部分情况下需要使用到 Task.WhenAll 方法,代码行数不少.另外,在需要获取多个异步任务的返回值 ...

  8. 实验8 #第8章 Verilog有限状态机设计-2 #Verilog #Quartus #modelsim

    2. 汽车尾灯控制器 2.1 实验要求:设计一个汽车尾灯控制电路. (1)功能:汽车左右两侧各有3个尾灯,要求控制尾灯按如下规则亮灭. 汽车沿直线行驶时,两侧指示灯全灭. 右转弯时,左侧的指示灯全灭, ...

  9. SQL Server实战三:数据库表完整性约束及索引、视图的创建、编辑与删除

      本文介绍基于Microsoft SQL Server软件,实现数据库表完整性约束.索引与视图的创建.编辑与删除等操作的方法. 目录 1 交互式为数据库表S创建PRIMARY KEY约束 2 交互式 ...

  10. 程序员天天 CURD,怎么才能成长,职业发展的思考 ?

    前言 关于程序员成长的话题,我前面写过一篇文章 - 程序员天天CURD,职业生涯怎么发展的思考. 现在回头看,对程序员这个职业发展的认识以及怎么发展还是有一些局限性.有一句话是这么说的:人的成长就是不 ...