Java基础巩固——JDK 8、9新增接口的特性(接口中定义非抽象方法、静态方法和私有方法)

#Java学了这么久,项目也做了?基础知识还不巩固?快来关注我的这篇系列博客——Java基础复习巩固吧#

目录

引言

一、JDK8新特性:允许在接口中定义非抽象方法和静态方法。

注意事项

 二、JDK9新特性:允许在接口中定义private私有方法。


引言

        Java中的接口起到了规范项目业务逻辑的作用,在JDK8以前,接口中的方法默认是抽象的,即只有方法的声明,没有方法的实现。

  • 从 JDK 8 开始,接口中可以定义非抽象方法和静态方法。
  • 从 JDK 9 开始,接口中可以定义私有方法和静态私有方法。

那么,Java设计师们为何要对借口进行这一系列的改进呢?下面请让我来为大家解答。

一、JDK8新特性:允许在接口中定义非抽象方法和静态方法。

新增特性:

  • 允许在接口中定义非抽象方法,但需要使用default关键字修饰,称为接口的默认方法;
  • 允许在借口中定义非抽象的静态方法

目的:解决接口升级的问题;

        例如,当团队的第一版项目成功上线,一段时间要对项目进行全面升级,要求丰富某一个接口的功能,新增8个方法;假如该项目中有100个类都实现了该接口,那么借口一旦改动,这100个类的都要重写新增方法,牵一发而动全身 。

        为了解决这个普遍问题,JDK8中允许接口中定义非抽象方法(通常称默认方法),实现该接口的类不用对默认方法进行重写而是可以直接继承,这极大减小了项目中升级接口的代价。

接口中默认方法的定义格式:

○格式: public  default  返回值类型  方法名(参数列表){}

○范例: public  default  void  show ( ) {....}

代码示例:

    //定义一个接口interface interA{void func01(); //抽象方法func1default void method(){System.out.println("我是接口中的默认方法method...");}}//定义一个类A,实现接口interAclass A implements interA{@Overridepublic void func01() {System.out.println("我是方法func01,我被重写了...");}}//定义一个类B,实现接口interAclass B implements interA{@Overridepublic void func01() {System.out.println("我是方法func01,我被重写了...");}}
public class Test {public static void main(String[] args) {A a = new A();a.method();}
}

 输出:我是接口中的默认方法method...

        上述代码中,接口interA中有一个抽象方法func01()和一个默认方法method(),实现该接口的类A和类B必须重写接口中的func01()而无需重写默认方法method();而是直接继承了接口中的默认方法;类A的示例a可以直接调用默认方法method()

        此时的你可能会提出一个疑问:如果一个类实现了多个接口,而这些接口中存在相同名字的默认方法时,那么这个类到底继承的是那个接口中(方法名相同)的默认方法呢?

答案就是,编译器会先报错,提示你必须重写这个多个接口中(方法名相同)的默认方法。

   //定义两个接口interA和interBinterface interA{void funcA(); //抽象方法func1default void method(){System.out.println("我是接口A中的默认方法method...");}}interface interB{void funcB();default void method(){System.out.println("我是接口B中的默认方法method...");}}//定义一个类A,实现接口interA和interBclass A implements interA,interB{ //会报错@Overridepublic void funcA() {System.out.println("我是方法funcA,我被重写了...");}@Overridepublic void funcB() {System.out.println("我是方法funB,我被重写了...");}}

 此时类A上会报错,如下图:

test.A inherits unrelated defaults for method() from types test.interA and test.interB(类A从类型test.interA和test.interB继承了method()的不相关默认值)

重写method()方法就好了:

        那么既然JDK8都允许了接口中可以定义非抽象方法,在开放一点也无妨,随后静态方法也允许在接口中存在。且只能通过接口名来调用

代码格式如下:

    //定义一个接口interinterface inter {//在该接口中定义一个静态方法func()public static void func(){System.out.println("我是接口中的静态方法func");}}

 用借口名来调用接口中的静态方法:

public class Test {public static void main(String[] args) {inter.func();}
}

输出:我是接口中的静态方法func

注意事项: 

1.接口中的默认方法:

  • 接口中的所有方法默认都是公有的,因此public可以省略,但default不能省略。

  • 接口的实现类允许重写接口中的默认方法,重写时要去掉default关键字。

  • 如果某个类实现了多个接口,且这多个接口中存在相同的默认方法,则实现类必须重写这个默认方法

 2.接口中的静态方法:

  • 关键字public可以省略,但static不能省略。

  • 接口中的静态方法,只允许通过接口名进行调用,不允许该接口实现类的对象调用

 二、JDK9新特性:允许在接口中定义private私有方法。

初学者小伙伴你是否有疑问?接口中的私有方法,实现类无法继承,也无法使用,有啥意义啊?

下面请看一个例子:

    //定义一个接口interinterface inter {//在该接口有多个默认方法,且都有相同的代码部分default void start(){System.out.println("执行start方法....");System.out.println("请求资源");System.out.println("更新日志");System.out.println("保存日志");}default void login(){System.out.println("执行login方法....");System.out.println("请求资源");System.out.println("更新日志");System.out.println("保存日志");}default void end(){System.out.println("执行end方法....");System.out.println("请求资源");System.out.println("更新日志");System.out.println("保存日志");}}

        由于接口中可以定义非抽象方法了,那么就有可能有重复的代码逻辑,上述代码有大量的重复内容,若通过编写一个默认方法来封装并代替这些重复代码,那么这个多写的默认方法就会被接口的实现类继承(一个无实际业务逻辑的方法不应当被继承),当有了私有方法后,就可以借助私有方法:

    interface inter {//在该接口有多个默认方法default void start(){System.out.println("执行start方法....");log();}default void login(){System.out.println("执行login方法....");log();}default void end(){System.out.println("执行end方法....");log();}private void log(){System.out.println("请求资源");System.out.println("更新日志");System.out.println("保存日志");}}

        此时借用私有方法来封装这些重复的代码逻辑,来减少代码量;确保这些重复的代码逻辑不被实现类继承,并且实现代码的复用。

作用:提升代复用性,减少冗余代码

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

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

相关文章

ScriptableObject使用

资料 Scripting/Create modular game architecture in Unity with ScriptableObjects 脚本文档 基础 SO是一个Unity对象,继承UnityEngine.Objec, SO最大的特点是实例文件可共享,有点类似静态数据,同一个实例文件可被多个对象引…

matlab实验:实验六MATLAB 数值计算与符号运算

题目1:(线性方程组数值求解) 1. 用不同的方法求解下面方程:(方程原式参考 P369 实验 10,第 1 题) 第 1 种,左除和求逆函数(inv) 第 2 种 , 用 符 号 运 算 的…

JAVA基础知识4(static、继承)

JAVA基础知识4 static静态成员变量静态成员方法解释注意点 继承父类(基类或超类)子类(派生类)使用继承的示例解释运行结果 成员变量的访问特点成员方法的访问特点构造方法的访问特点 Java项目,包和类之间的联系包的概念…

vue elementui 在table里使用el-switch

<el-table-columnprop"operationStatus"label"状态"header-align"center"align"center"><template slot-scope"scope"><el-switch active-value"ENABLE" inactive-value"DISABLE" v-mod…

使用框架构建React Native应用程序的最佳实践

在React Conf上&#xff0c;我们更新了关于开始构建React Native应用程序的最佳工具的指导&#xff1a;一个React Native框架——一个包含所有必要API的工具箱&#xff0c;让您能够构建生产就绪的应用程序。 现在推荐使用React Native框架&#xff08;如Expo&#xff09;来创建…

Spring 依赖注入02

文章目录 1. 核心概念2. 依赖注入的方式3. 构造函数注入3.1 构造函数注入的优点包括&#xff1a; 4. 设值注入4.1 设值注入的特点和优点4.2 使用设值注入的注意事项 5. 接口注入5.1 接口注入的基本概念&#xff1a;5.2 使用接口注入的注意事项&#xff1a; 依赖注入&#xff08…

代码随想录day23 ||39组合总和1 40组合总和2 131分割回文串

39组合总和1 力扣题目链接 题目描述&#xff1a; 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target &#xff0c;找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 &#xff0c;并以列表形式返回。你可以按 任意顺序 返回这些组合。 cand…

【C语言】两个数组比较详解

目录 C语言中两个数组比较详解1. 逐元素比较1.1 示例代码1.2 输出结果1.3 分析 2. 内置函数的使用2.1 示例代码2.2 输出结果2.3 分析 3. 在嵌入式系统中的应用3.1 示例代码3.2 输出结果3.3 分析 4. 拓展技巧4.1 使用指针优化比较4.2 输出结果4.3 分析 5. 表格总结6. 结论7. 结束…

高级及架构师高频应用型面试题

一、微服务多节点批量应该怎么设计&#xff1f; 1、异步任务分类&#xff1a; 周期性定时任务调度任务批量任务 2、需要考虑并解决的问题&#xff1a; 2.1、避免同一任务同时被多个节点捞取。 1&#xff09;数据库的行级锁 2&#xff09;redis分布式锁 3&#xff09;quartz…

后端面试题日常练-day06 【Java基础】

题目 希望这些选择题能够帮助您进行后端面试的准备&#xff0c;答案在文末 在Java中&#xff0c;以下哪个关键字用于表示类之间的关联性&#xff0c;表明一个类包含另一个类的对象&#xff1f; a) include b) contain c) reference d) composition Java中的方法重写&#xff…

Python写UI自动化--playwright(通过UI文本匹配实现定位)

本篇简单拓展一下元素定位技巧&#xff0c;通过UI界面的文本去实现定位 目录 匹配XPath 匹配文本元素 .count()统计匹配数量 处理匹配文本返回多个元素 1、使用.nth(index)选择特定元素: 2、获取所有匹配的元素并遍历: 3、错误处理: 匹配XPath 比如我们要定位到下图的…

C++笔试强训8

文章目录 一、选择题1-5题6-10题 二、编程题题目一题目二 一、选择题 1-5题 根据下面的定义故选A。 函数重载:在相同作用域中&#xff0c;函数名字相同&#xff0c;参数列表不同的一系列函数称为函数重载参数列表不同具体的体现:参数个数不同参数类型不同类型的次序不同注意:…

单元测试--Junit

Junit是Java的单元测试框架提供了一些注解方便我们进行单元测试 1. 常用注解 常用注解&#xff1a; TestBeforeAll&#xff0c;AfterAllBeforeEach&#xff0c;AfterEach 使用这些注解需要先引入依赖&#xff1a; <dependency><groupId>org.junit.jupiter<…

6 C 语言指针的奥秘:理论与实践详解

目录 1 变量访问机制 1.1 内存地址 1.2 变量的直接访问 1.3 变量的间接访问 2 指针变量及其内存大小 2.1 指针与指针变量 2.2 指针变量的定义格式 2.3 指针变量的内存大小 3 取地址操作符与取值操作符 3.1 取地址操作符 & 3.2 取值操作符 * 3.3 解引用与数据类…

Xcode是什么?它在iOS开发中的作用和功能有哪些?

Xcode是苹果公司为macOS平台开发的一款集成开发环境&#xff08;Integrated Development Environment&#xff0c;简称IDE&#xff09;&#xff0c;它主要用于开发iOS、iPadOS、macOS、watchOS和tvOS的应用程序。Xcode集成了从编写代码、界面设计、调试程序、版本控制到应用发布…

【数据结构】顺序表(杨辉三角、简单的洗牌算法)

&#x1f387;&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了 博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳&#xff0c;欢迎大佬指点&#xff01; 欢迎志同道合的朋友一起加油喔 &#x1f4aa;&#x1f4aa;&#x1f4aa; 谢谢你这么帅…

pandas.core.series.Series 转json

在Python中&#xff0c;可以使用Pandas库中的Series.to_json()方法将Series对象转换为JSON格式的字符串。以下是一个简单的例子&#xff1a; import pandas as pd# 创建一个Pandas Seriess pd.Series({a: 1, b: 2, c: 3})# 转换为JSON字符串json_str s.to_json(orientrecords…

Android SurfaceFlinger——通知消费流程(三十五)

上一篇文章介绍了 onFrameAvailable() 函数的流程&#xff0c;最终回调到了 BLASTBufferQueue 中&#xff0c;这里测处理跟 Android 老版本还是有区别的&#xff0c;在 BLASTBufferQueue 中通过提交事务的方式通知 SurfaceFlinger 进行更新&#xff0c;而不是老版本中的直接调用…

学习React(描述 UI)

React 是一个用于构建用户界面&#xff08;UI&#xff09;的 JavaScript 库&#xff0c;用户界面由按钮、文本和图像等小单元内容构建而成。React 帮助你把它们组合成可重用、可嵌套的 组件。从 web 端网站到移动端应用&#xff0c;屏幕上的所有内容都可以被分解成组件。在本章…

netty应用-手写RPC

文章目录 手写RPC之案例定位与通信过程介绍RPC框架案例定位服务端与客户端架构通信过程1. 服务注册与发现2. 请求序列化与传输3. 请求处理与响应4. 响应反序列化与结果处理实现细节1. 服务端2. 客户端技术选型关键挑战总结手写RPC之请求响应通信协议定制协议结构示例消息头格式…