java8默认方法

口什么是默认方法
口如何以一种兼容的方式改进API
口默认方法的使用模式
口 解析规则


传统上,Java程序的接口是将相关方法按照约定组合到一起的方式。实现接口的类必须为接口中定义的每个方法提供一个实现,或者从父类中继承它的实现。但是,一旦类库的设计者需要更新接口,向其中加入新的方法,这种方式就会出现问题。现实情况是,现存的实体类往往不在接口设计者的控制范围之内,这些实体类为了适配新的接口约定也需要进行修改。由于Java8的API在现存的接口上引入了非常多的新方法,这种变化带来的问题也愈加严重,一个例子就是前几章中使用过的List接口上的sort方法。想象一下其他备选集合框架的维护人员会多么抓狂吧像Guava和Apache Comons这样的框架现在都需要修改实现了List接口的所有类,为其添加sort方法的实现。
且慢,其实你不必惊慌。Java8为了解决这一问题引人了一种新的机制。Java8中的接口现在支持在声明方法的同时提供实现,这听起来让人惊讶!通过两种方式可以完成这种操作。

其一,Java8允许在接口内声明静态方法。

其二,Java8引人了一个新功能,叫默认方法,通过默认方法你可以指定接口方法的默认实现。换句话说,接口能提供方法的具体实现。因此,实现接口的类如果不显式地提供该方法的具体实现,就会自动继承默认的实现。这种机制可以使你平滑地进行接口的优化和演进。实际上,到目前为止你已经使用了多个默认方法。两个例子就是你前面已经见过的List接日中的sort,以及Collection接日中的stream。第1章中我们看到的List接口中的sort方法是Java8中全新的方法,它的定义如下:

default void sort(Comparator<?super E>c){
Collections.sort(this,c)
}

请注意返回类型之前的新aefau1t修饰符。通过它,我们能够知道一个方法是否为默认方法。这里sort方法调用了collections.sort方法进行排序操作。由于有了这个新的方法,

简而言之,向接口添加方法是诸多问题的罪恶之源;一旦接口发生变化,实现这些接口的类往往也需要更新,提供新添方法的实现才能适配接口的变化。如果你对接口以及它所有相关的实现有完全的控制,这可能不是个大问题。但是这种情况是极少的。这就是引人默认方法的目的:它让类可以自动地继承接口的一个默认实现。
因此,如果你是个类库的设计者,这一章的内容对你而言会十分重要,因为默认方法为接口的演进提供了一种平滑的方式,你的改动将不会导致已有代码的修改。此外,正如我们后文会介绍的,默认方法为方法的多继承提供了一种更灵活的机制,可以帮助你更好地规划你的代码结构:类可以从多个接口继承默认方法。因此,即使你并非类库的设计者,也能在其中发现感兴趣的东西。
静态方法及接口
同时定义接口以及工具辅助类(companion class)是Java语言常用的一种模式,工具类定义了与接口实例协作的很多静态方法。比如,Collections就是处理collection对象的辅助类。由于静态方法可以存在于接口内部,你代码中的这些辅助类就没有了存在的必要,你可以把这些静态方法转移到接口内部。为了保持后向的兼容性,这些类依然会存在于Java应用程序的接口之中。
本章的结构如下。首先,我们会跟你一起剖析一个API演化的用例,探讨由此引发的各种问题。紧接着我们会解释什么是默认方法,以及它们在这个用例中如何解决相应的问题。之后,我们会展示如何创建自己的默认方法,构造Java语言中的多继承。最后,我们会讨论一个类在使用一个签名同时继承多个默认方法时,Java编译器是如何解决可能的二义性(模糊性)问题的。

默认方法9.2
经过前述的介绍,我们已经了解了向已发布的API添加方法,对现存代码实现会造成多大的损害。默认方法是Java8中引人的一个新特性,希望能借此以兼容的方式改进API。现在,接口包含的方法签名在它的实现类中也可以不提供实现。那么,谁来具体实现这些方法呢?实际上,缺失的方法实现会作为接口的一部分由实现类继承(所以命名为默认实现),而无需由实现类提供那么,我们该如何辨识哪些是默认方法呢?其实非常简单。默认方法由defau1t修饰符修饰并像类中声明的其他方法一样包含方法体。比如,你可以像下面这样在集合库中定义一个名为sizea的接口,在其中定义一个抽象方法size,以及一个默认方法

isEmpty:
public interface sized{
int size()idefault boolean isEmpty(){return size()==0


这样任何一个实现了sizea接口的类都会自动继承isEmpty的实现。因此,向提供了默认实现的接口添加方法就不是源码兼容的。

现在,我们回顾一下最初的例子,那个Java画图类库和你的游戏程序。具体来说,为了以兼容的方式改进这个库(即使用该库的用户不需要修改他们实现了Resizable的类),可以使用默,

 解决冲突的规则
我们知道Java语言中一个类只能继承一个父类,但是一个类可以实现多个接口。随着默认方法在Java 8中引人,有可能出现一个类继承了多个方法而它们使用的却是同样的函数签名。这种情况下,类会选择使用哪一个函数?在实际情况中,像这样的冲突可能极少发生,但是一旦发生这样的状况,必须要有一套规则来确定按照什么样的约定处理这些冲突。这一节中,我们会介绍Java编译器如何解决这种潜在的冲突。我们试图回答像“接下来的代码中,哪一个hello方法是被c类调用的”这样的问题。注意,接下来的例子主要用于说明容易出问题的场景,并不表示这些场景在实际开发过程中会经常发生。
public interface {default void hello(){System.out.println("Hello from ");
public interface Bextends default void hello(){System.out.println("Hello from B");
public classcimplementsB.public static void main(string...args){new C)helle()i
猜猜打印输出
的是什么?
此外,你可能早就对C++语言中著名的荾形继承问题有所了解,菱形继承问题中一个类同时继承了具有相同函数签名的两个方法。到底该选择哪一个实现呢?Java8也提供了解决这个问题的方案。请接着阅读下面的内容。
9.4.1 解决问题的三条规则
如果一个类使用相同的函数签名从多个地方(比如另一个类或接口)继承了方法,通过三条
规则可以进行判断。

(1)类中的方法优先级最高。类或父类中声明的方法的优先级高于任何声明为默认方法的优先级。
(2)如果无法依据第一条进行判断,那么子接口的优先级更高:函数签名相同时,优先选择

(3)最后,如果还是无法判断,继承了多个接口的类必须通过显式覆盖和调用期望的方法

显式地选择使用哪一个默认方法的实现。
我们保证,这些就是你需要知道的全部!让我们一起看几个例子。
9.4.2 选择提供了最具体实现的默认方法的接口
让我们回顾一下本节开头的例子,这个例子中c类同时实现了B接口和A接口,而这两个接口恰巧又都定义了名为he1lo的默认方法。另外,B继承自。图9-5是这个场景的UML图。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/471637.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《苍穹外卖》知识梳理6-缓存商品,购物车功能

苍穹外卖实操笔记六—缓存商品&#xff0c;购物车功能 一.缓存菜品 可以使用redis进行缓存&#xff1b;另外&#xff0c;在实现缓存套餐时可以使用spring cache提高开发效率&#xff1b;   通过缓存数据&#xff0c;降低访问数据库的次数&#xff1b; 使用的缓存逻辑&#…

【C语言】Linux内核accept 系统调用代码

一、Linux 4.19内核accept 系统调用代码中文注释 /** 在使用accept时&#xff0c;我们尝试创建一个新的socket&#xff0c;与客户端建立连接&#xff0c;* 唤醒客户端&#xff0c;然后返回新的连接文件描述符&#xff08;fd&#xff09;。我们在内核空间收集* 连接方的地址&am…

laravel_框架结构和文件夹_简单分析

文章目录 简单看一下laravel框架的目录结构illuminate_一柳梅内特的含义illuminate下面有多少文件夹的&#xff1f;介绍一下illuminate下面的文件夹功能我的分类 简单看一下laravel框架的目录结构 illuminate_一柳梅内特的含义 作为及物动词&#xff0c;它的意思是“阐明&…

leetcode hot 100最小花费爬楼梯

本题和之前的爬楼梯类似&#xff0c;但是需要考虑到花费的问题&#xff01;**注意&#xff0c;只有在爬的时候&#xff0c;才花费体力&#xff01;**那么&#xff0c;我们还是按照动态规划的五部曲来思考。 首先我们要确定dp数组的含义&#xff0c;那么就是我们爬到第i层所花费…

【机器学习案例5】语言建模 - 最常见的预训练任务一览表

自监督学习 (SSL) 是基于 Transformer 的预训练语言模型的支柱,该范例涉及解决有助于建模自然语言的预训练任务 (PT)。本文将所有流行的预训练任务放在一起,以便我们一目了然地评估它们。 SSL 中的损失函数 这里的损失函数只是模型训练的各个预训练任务损失的加权和。 以BE…

计算组合数C(n,k)即从n个不同元素中选取k个元素的方法数binom()

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 计算组合数C(n,k) 即从n个不同元素中 选取k个元素的方法数 binom() [太阳]选择题 以下代码的输出结果中正确的是? from scipy.special import binom print("【执行】binom(3, 2)"…

LabVIEW虚拟测试与分析仪

LabVIEW虚拟测试与分析仪 在现代工程技术领域&#xff0c;虚拟仪器的开发和应用已成为一种趋势。利用LabVIEW软件平台开发的虚拟测试与分析仪器进行展开&#xff0c;实现工程测试和分析中的实际需求。通过结合LabVIEW的强大功能和灵活性&#xff0c;成功实现了一套高效、精确的…

嵌入式STM32 单片机 GPIO 的工作原理详解

STM32的 GPIO 介绍 GPIO 是通用输入/输出端口的简称&#xff0c;是 STM32 可控制的引脚。GPIO 的引脚与外部硬件设备连接&#xff0c;可实现与外部通讯、控制外部硬件或者采集外部硬件数据的功能。 以 STM32F103ZET6 芯片为例子&#xff0c;该芯片共有 144 脚芯片&#xff0c…

算法沉淀——BFS 解决 FloodFill 算法(leetcode真题剖析)

算法沉淀——BFS 解决 FloodFill 算法 01.图像渲染02.岛屿数量03.岛屿的最大面积04.被围绕的区域 BFS&#xff08;广度优先搜索&#xff09;解决 Flood Fill 算法的基本思想是通过从起始点开始&#xff0c;逐层向外扩展&#xff0c;访问所有与起始点相连且具有相同特性&#xf…

CF1845 D. Rating System [思维题+数形结合]

传送门:CF [前题提要]:自己在做这道题的时候思路完全想错方向,导致怎么做都做不出来,看了题解之后感觉数形结合的思考方式挺好的(或者这种做法挺典的),故写篇题解记录一下 题目很简单,不再解释.先不考虑 k k k,想想是一种什么情况?很显然应该是跟下图一样是一个折线图的变化.…

2024-02-16 AIGC-数字人-平台调研-记录

摘要: 2024-02-16 AIGC-数字人-平台调研 需求分析: 数字人-平台调研 南京硅基智能北京风平智能[风平科技]品达集团[杭州品达企服科技(集团)有限公司]花脸数字技术灰豚数字人[温州专帮信息科技有限公司]魔珐科技数字栩生公司官网guiji-ows风平智能 - 领先的AIGC解决方案提供商。…

【Linux】Linux编译器-gcc/g++ Linux项目自动化构建工具-make/Makefile

目录 Linux编译器-gcc/g使用 1.背景知识 Linux中头文件的目录在 Linux 库 条件编译的典型应用 2.gcc如何完成 动态库 vs 静态库 debug && release Linux项目自动化构建工具-make/Makefile 背景 用法 特殊符号 Linux编译器-gcc/g使用 1.背景知识 预处理&am…