接口里面可以写实现方法吗【可以】 、接口可以多继承吗【可以】
比如下面这道题:
问:接口里面可以写方法吗?
答:当然可以啊,默认就是抽象方法。
.
问:那接口里面可以写实现方法吗?
答:不可以,所有方法必须是抽象的。
.
问:你确定吗?
答:确定……
面试同学看起来对这问题有点怀疑人生,最后还是斩钉截铁的告诉面试官:接口里面只能写抽象方法,不能写实现方法。
问:接口里面是可以写实现方法的,Java 8 开始就可以了,你用过 Java 8 吗?
答:好吧,看来是我学艺不精,Java 8有了解一点,比如那个 Lambda 表达式,但实际项目中也没怎么用。
通过这些交流,能看出,虽然开发版本用的是 Java 8,但实际用的还是 Java 8 之前的最基础的语法。
Java 8 至 2014 年发布至今,已经过了 6 个年头了,最新的 Java 14 都发布了,OK?我们围绕着问题展开。
▌什么是默认方法和静态方法?
上面也说了,Java 8 开始是可以有方法实现的,可以在接口中添加默认方法和静态方法。
默认方法用 default 修饰,只能用在接口中,静态方法用 static 修饰,这个我们不陌生了。并且接口中的默认方法、静态方法可以同时有多个。
在接口中写实现方法一点也不稀奇,像这样的用法,从 Java 8 到 Java 14 已是遍地开花,到处都可以看到接口默认方法和静态方法的身影。
比如我们来看下在 JDK API 中 java.util.Map 关于接口默认方法和静态方法的应用。
public interface Map<K,V> {.../*** 接口默认方法*/default boolean remove(Object key, Object value) {Object curValue = get(key);if (!Objects.equals(curValue, value) ||(curValue == null && !containsKey(key))) {return false;}remove(key);return true;}.../*** 接口静态方法*/public static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K,V>> comparingByKey() {return (Comparator<Map.Entry<K, V>> & Serializable)(c1, c2) -> c1.getKey().compareTo(c2.getKey());}...}
▌为什么要有接口默认方法?
举一个很现实的例子:
我们的接口老早就写好了,后面因为各种业务问题,避免不了要修改接口。
在 Java 8 之前,比如要在一个接口中添加一个抽象方法,那所有的接口实现类都要去实现这个方法,不然就会编译错误,而某些实现类根本就不需要实现这个方法也被迫要写一个空实现,改动会非常大。
所以,接口默认方法就是为了解决这个问题,只要在一个接口添加了一个默认方法,所有的实现类就自动继承,不需要改动任何实现类,也不会影响业务,爽歪歪。
另外,接口默认方法可以被接口实现类重写。
▌为什么要有接口静态方法?
接口静态方法和默认方法类似,只是接口静态方法不可以被接口实现类重写。
接口静态方法只可以直接通过静态方法所在的 接口名.静态方法名 来调用。
▌接口默认方法多继承冲突问题
因为接口默认方法可以被继承并重写,如果继承的多个接口都存在相同的默认方法,那就存在冲突问题。
下面我会列举 3 个冲突示例场景。
冲突一
来看下面这段程序:
interface People {default void eat(){System.out.println("人吃饭");}
}interface Man {default void eat(){System.out.println("男人吃饭");}
}interface Boy extends Man, People {}
Boy 同时继承了 People 和 Man,此时在 IDEA 编辑器中就会报错:

这就是接口多继承带来的冲突问题,Boy 不知道该继承谁的,这显然也是个问题,IDEA 也会提示,需要重写这个方法才能解决问题:
interface Boy extends Man, People {@Overridedefault void eat() {System.out.println("男孩吃饭");}
}
在方法里面还能直接调用指定父接口的默认方法,比如:
interface Boy extends Man, People {@Overridedefault void eat() {People.super.eat();Man.super.eat();System.out.println("男孩吃饭");}
}
再加个实现类测试一下:
static class Student implements Boy {public static void main(String[] args) {Student student = new Student();student.eat();}}
输出:
人吃饭
男人吃饭
男孩吃饭
嗯,很强大!
冲突二
我们再换一种写法,把 Man 继承 People,然后 Man 重写 People 中的默认方法。

此时,编辑器不报错了,而 People 的默认方法置灰了,提示没有被用到。
再运行一下上面的示例,输出:
男人吃饭
因为 Man 继承 People,Man 又重写了默认方法。很显然,这个时候,Boy 知道该继承谁的默认方法了。
冲突三
在 Man 接口中新增一个方法:say,然后在 Boy 接口中新增一个默认方法:say。

这时候,Man 中的抽象方法居然被忽略了,IDEA 都提示说没用到,这显然是默认方法优先于抽象方法。
▌总结
本文介绍了 Java 8 的默认方法和静态方法,以及默认方法的冲突问题解决方案。所以,再也不要说接口不能写实现方法了,那就太 OUT 了。。
文中只举了 3 个默认方法的冲突场景,不确定还没有更多冲突问题。
默认方法虽然解决了接口变动带来的问题,但如果设计不当,或者过度设计,其带来的方法冲突问题也是需要引起注意的。
相关文章:
接口里面可以写实现方法吗【可以】 、接口可以多继承吗【可以】
比如下面这道题: 问: 接口里面可以写方法吗? 答: 当然可以啊,默认就是抽象方法。 . 问: 那接口里面可以写实现方法吗? 答: 不可以,所有方法必须是抽象的。 . 问: 你确定吗࿱…...
【YOLOv8/YOLOv7/YOLOv5/YOLOv4/Faster-rcnn系列算法改进NO.57】引入可形变卷积
文章目录前言一、解决问题二、基本原理三、添加方法四、总结前言 作为当前先进的深度学习目标检测算法YOLOv8,已经集合了大量的trick,但是还是有提高和改进的空间,针对具体应用场景下的检测难点,可以不同的改进方法。此后的系列…...
统计学习--三种常见的相关系数
1)Pearson积差相关系数:用于量度两个变量X和Y之间的线性相关。它具有1和-1之间的值,其中1是总正线性相关性,0是非线性相关性,并且-1是总负线性相关性。Pearson相关系数的一个关键数学特性是它在两个变量的位置和尺度的…...
基于Django4.1.4的入门学习记录
基于Django4.1.4的入门学习记录Django创建Django项目创建工程工程目录说明运行开发服务器settings.py配置文件应用的创建创建应用模块应用模块文件说明App应用配置注册安装子应用数据模型ORM概述定义模型类生成数据库表查看数据库文件Admin管理工具管理界面本地化创建管理员注册…...
C++ Butterworth N阶滤波器设计
介绍一个 Butterworth Nth 滤波器设计系数的函数,像 Matlab 函数一样的: [bl,al]butter(but_order,Ws); 和 [bh,ah]butter(but_order,2*bandwidth(1)/fs,high);rtfilter 在 Ububtu 中,容易找到: $ aptitude search ~dbutterwo…...
UXP下不用任何框架创建自己的插件并试运行
在上一篇文章中《Windows下vue框架下的UXP插件开发环境搭建及程序试运行》,搭建的是利用vue框架进行开发的UXP开发环境,而且是把官方的案例插件直接添加进UDT,下面要说的是不利用任何js的框架创建和试运行自己的UXP插件程序,这样来…...
mac修改国内源快速安装brew
我是参考了清华源官网,有任何困惑直接访问该网址即可。这里给出精简版。 1. 更改镜像到~/.zshrc 终端添加方式 echo export HOMEBREW_API_DOMAIN"https://mirrors.tuna.tsinghua.edu.cn/homebrew-bottles/api" >> ~/.zshrcecho export HOMEBREW_…...
Me-and-My-Girlfriend-1靶场通关
Me-and-My-Girlfriend-1靶场通关 靶机ip:192.168.112.135 信息收集 端口:22、80 还是从80WEB服务器端口入手 对服务器目录进行扫描,扫出以下目录 访问80端口WEB服务,显示一段文字只允许本地用户访问。 一眼伪造ip,查看页面…...
2.6 棋盘覆盖
在一个2*x2‘个方格组成的棋盘中,若怡有一个方格与其他方格不同,则称该方格为特殊方格,且称该棋盘为一特殊棋盘。显然,特殊方格在棋盘上出现的位置有 4种情形因而对任何k0,有4‘种特殊棋盘。图2-4 申的特殊棋益是12时 …...
JMU软件20 大数据技术复习(只写了对比18提纲的变动部分)
原博主 博客主页:https://xiaojujiang.blog.csdn.net/ 原博客链接:https://blog.csdn.net/qq_43058685/article/details/117883940 本复习提纲只适用于JMU软件工程大数据课程(ckm授课) 具体内容参考老师提纲的考纲,18和…...
MySQL底层存储B-Tree和B+Tree原理分析
1.B-Tree的原理分析 (1)什么是B-Tree B-树,全称是 Balanced Tree,是一种多路平衡查找树。 一个节点包括多个key (数量看业务),具有M阶的B树,每个节点最多有M-1个Key。 节点的key元素个数就是指这个节点能…...
基于Vue+Vue-cli+webpack搭建渐进式高可维护性前端实战项目
本文是专栏《手把手带你做一套毕业设计毕业设计》的实战第一篇,将从Vue脚手架安装开始,逐步带你搭建起一套管理系统所需的架构。当然,在默认安装完成之后,会对文件目录进行初步的细化拆分,以便后续功能迭代和维护所用。…...
第十三章:Java反射机制
第十三章:Java反射机制 13.1:Java反射机制概述 Java Reflection Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法。 加…...
iLok USB不识别怎么办?
我的iLok USB坏了吗? 我的iLok USB没有被系统或软件识别。 如果您的iLok USB未被识别,问题可能出在iLok USB、iLok软件或受保护的软件。 提示如果您使用USB集线器,请确保您使用正确的集线器电源适配器。排除硬件:将iLok USB直接插…...
【LeetCode与《代码随想录》】二叉树篇:做题笔记与总结-JavaScript版
文章目录代码随想录144. 二叉树的前序遍历94. 二叉树的中序遍历145. 二叉树的后序遍历102.二叉树的层序遍历226.翻转二叉树101. 对称二叉树104.二叉树的最大深度111.二叉树的最小深度222.完全二叉树的节点个数110.平衡二叉树257. 二叉树的所有路径404.左叶子之和513.找树左下角…...
机器人运动|浅谈Time Elastic Band算法
前言在自主移动机器人路径规划的学习与开发过程中,我接触到Time Elastic Band算法,并将该算法应用于实际机器人,用于机器人的局部路径规划。在此期间,我也阅读了部分论文、官方文档以及多位大佬的文章,在此对各位大佬的…...
【Linux】网络基础(1)
前言 相信没有网络就没有现在丰富的世界。本篇笔记记录我在Linux系统下学习网络基础部分知识,从关于网络的各种概念和关系开始讲起,逐步架构起对网络的认识,对网络编程相关的认知。 我的上一篇Linux文章呀~ 【Linux】网络套接字编程_柒海啦的…...
限流算法详解
限流是我们经常会碰到的东西,顾名思义就是限制流量。它能保证我们的系统不会被突然的流量打爆,保证系统的稳定运行。像我们生活中,地铁就会有很多护栏,弯弯绕绕的,这个就是一种限流。像我们抢茅台,肯定大部…...
Spark/Hive
Spark/HiveHive 原理Spark with HiveSparkSession Hive Metastorespark-sql CLI Hive MetastoreBeeline Spark Thrift ServerHive on SparkHive 擅长元数据管理Spark 擅长高效的分布式计算 Spark Hive 集成 : Hive on Spark : Hive 用 Spark 作为底层的计算引擎时Spark w…...
HashMap底层的实现原理(JDK8)
目录一、知识点回顾二、HashMap 的 put() 和 get() 的实现2.1 map.put(k, v) 实现原理2.2 map.get(k) 实现原理三、HashMap 的常见面试题3.1 为何随机增删、查询效率都很高?3.2 为什么放在 HashMap 集合 key 部分的元素需要重写 equals 方法?3.3 HashMap 的 key 为…...
深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...
FFmpeg 低延迟同屏方案
引言 在实时互动需求激增的当下,无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作,还是游戏直播的画面实时传输,低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架,凭借其灵活的编解码、数据…...
Docker 运行 Kafka 带 SASL 认证教程
Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明:server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...
高危文件识别的常用算法:原理、应用与企业场景
高危文件识别的常用算法:原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件,如包含恶意代码、敏感数据或欺诈内容的文档,在企业协同办公环境中(如Teams、Google Workspace)尤为重要。结合大模型技术&…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...
优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...
基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...
tomcat指定使用的jdk版本
说明 有时候需要对tomcat配置指定的jdk版本号,此时,我们可以通过以下方式进行配置 设置方式 找到tomcat的bin目录中的setclasspath.bat。如果是linux系统则是setclasspath.sh set JAVA_HOMEC:\Program Files\Java\jdk8 set JRE_HOMEC:\Program Files…...
【LeetCode】算法详解#6 ---除自身以外数组的乘积
1.题目介绍 给定一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O…...
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...
