news 2026/4/18 8:24:43

java——接口——非抽象方法

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
java——接口——非抽象方法

文章目录

  • 背景
  • Java 接口与抽象类详解
    • 一、接口实现与部分实现的问题
      • 问题描述
      • 答案
      • 解决方案
      • 关键概念区分
      • 类型对比表
    • 二、接口中的 default 方法(第一次见到)
      • 问题描述
      • 答案
      • 接口方法的完整规则(Java 8+)
      • 为什么引入 default 方法?
      • 完整示例
    • 三、接口与抽象类的区别
      • 核心区别总结
      • 详细对比
        • 1. 多继承 vs 单继承
        • 2. 成员变量
        • 3. 构造方法
        • 4. this 和 super
        • 5. 访问控制
      • 使用场景示例
      • 组合使用示例
    • 四、选择建议
    • 五、总结
      • 关键要点
      • 一句话总结

背景

最近在某个代码中,看到了接口B extend 接口A,其实这种写法也正常,但第一次见的是 接口B中有非抽象方法,这就和之前背的八股文"接口中只能有抽象方法"相悖,但jdk确实支持这种写法,因为第一次见到这种写法,所以特此记录下

Java 接口与抽象类详解

一、接口实现与部分实现的问题

问题描述

假设有以下代码:

// 接口定义publicinterfaceAStudentInterface{voidmethod1();voidmethod2();voidmethod3();}// 类实现接口publicclassBStudentClassimplementsAStudentInterface{@Overridepublicvoidmethod1(){// 实现了第一个方法}// method2 和 method3 没有实现}

问题BStudentClass是接口还是类?如果只实现了部分抽象方法会怎样?

答案

BStudentClass是一个,不是接口。

如果普通类只实现了接口的部分方法,编译会报错

错误: BStudentClass不是抽象的, 并且未覆盖AStudentInterface中的抽象方法method2()

解决方案

方案一:声明为抽象类

publicabstractclassBStudentClassimplementsAStudentInterface{@Overridepublicvoidmethod1(){// 实现了一个方法}// method2 和 method3 保持抽象状态,不需要实现}

方案二:实现所有方法

publicclassBStudentClassimplementsAStudentInterface{@Overridepublicvoidmethod1(){/* 实现 */}@Overridepublicvoidmethod2(){/* 实现 */}@Overridepublicvoidmethod3(){/* 实现 */}}

关键概念区分

语法关键字说明
类实现接口implements类去实现接口
类继承类extends子类继承父类
接口继承接口extends子接口继承父接口

类型对比表

类型关键字是否需要实现所有接口方法能否实例化
普通类class✅ 必须全部实现✅ 可以
抽象类abstract class❌ 可以部分实现❌ 不可以
接口interface不适用(接口定义方法签名)❌ 不可以

二、接口中的 default 方法(第一次见到)

问题描述

// 接口定义publicinterfaceAStudentInterface{voidmethod1();voidmethod2();voidmethod3();}publicinterfaceBStudentInterfaceextendsAStudentInterface{@Overridedefaultvoidmethod1(){// 具体实现}}

问题:接口中不是只允许存在抽象方法吗?为什么实现了 method1 方法,还是个接口?

答案

BStudentInterface仍然是一个接口,这是合法的写法。

原因:从 Java 8 开始,接口可以包含具有具体实现的方法,称为default 方法(默认方法)

接口方法的完整规则(Java 8+)

方法类型关键字是否有实现是否必须实现
抽象方法无(默认)❌ 无✅ 实现类必须实现
默认方法default✅ 有❌ 可选,可以覆盖
静态方法static✅ 有不适用,通过接口调用
私有方法private(Java 9+)✅ 有不适用,接口内部使用

为什么引入 default 方法?

问题场景:假设AStudentInterface被 100 个类实现了,现在想给接口新增一个方法:

publicinterfaceAStudentInterface{voidmethod1();voidmethod2();voidmethod3();voidmethod4();// ❌ 编译错误!100个实现类都要改}

解决方案:使用 default 方法

publicinterfaceAStudentInterface{voidmethod1();voidmethod2();voidmethod3();defaultvoidmethod4(){System.out.println("默认实现");}}

这样,已有的实现类不需要修改,都能继承这个默认实现。

完整示例

// 父接口publicinterfaceAStudentInterface{voidmethod1();voidmethod2();voidmethod3();}// 子接口:用 default 实现部分方法publicinterfaceBStudentInterfaceextendsAStudentInterface{@Overridedefaultvoidmethod1(){System.out.println("method1 的默认实现");}// method2 和 method3 仍然是抽象方法}// 实现类publicclassStudentImplimplementsBStudentInterface{@Overridepublicvoidmethod2(){System.out.println("实现 method2");}@Overridepublicvoidmethod3(){System.out.println("实现 method3");}// method1 可以直接使用默认实现,也可以覆盖}

三、接口与抽象类的区别

核心区别总结

特性接口抽象类
继承关系可以implements多个接口只能extends一个类
成员变量只能是public static final常量可以有各种类型的成员变量
构造方法❌ 没有✅ 有
代码块❌ 没有✅ 可以有静态块、实例块
方法修饰符默认 public可以是任意访问修饰符
this/super❌ 不能使用✅ 可以使用
设计理念定义"能做什么"(能力)定义"是什么"(本质)

详细对比

1. 多继承 vs 单继承
// ✅ 接口:可以实现多个publicclassStudentimplementsAStudentInterface,BStudentInterface,CStudentInterface{// ...}// ❌ 抽象类:只能继承一个publicclassStudentextendsAbstractStudent{// 只能一个// ...}
2. 成员变量
// 接口:只能有常量publicinterfaceBStudentInterfaceextendsAStudentInterface{intCOUNT=100;// 自动是 public static final// String name; // ❌ 编译错误// private int age; // ❌ 编译错误}// 抽象类:可以有各种变量publicabstractclassAbstractStudent{privateStringname;// ✅ 私有变量protectedintage;// ✅ 受保护变量publicstaticfinalintCOUNT=100;// ✅ 常量}
3. 构造方法
// 接口:没有构造方法publicinterfaceBStudentInterface{// public BStudentInterface() {} // ❌ 编译错误}// 抽象类:可以有构造方法publicabstractclassAbstractStudent{privateStringname;publicAbstractStudent(Stringname){// ✅ 构造方法this.name=name;}}
4. this 和 super
// 接口:不能使用 this 和 superpublicinterfaceBStudentInterface{defaultvoidmethod1(){// this.toString(); // ❌ 不允许// super.toString(); // ❌ 不允许System.out.println("default");}}// 抽象类:可以使用 this 和 superpublicabstractclassAbstractStudent{publicvoidmethod1(){this.toString();// ✅ 可以super.toString();// ✅ 可以}}
5. 访问控制
// 接口:方法默认是 publicpublicinterfaceBStudentInterface{voidmethod1();// 自动是 public// private void method2(); // ❌ Java 8 不支持// protected void method3(); // ❌ 不支持}// 抽象类:灵活的访问控制publicabstractclassAbstractStudent{publicvoidmethod1(){}// ✅ publicprotectedvoidmethod2(){}// ✅ protectedprivatevoidmethod3(){}// ✅ privateabstractvoidmethod4();// ✅ 包私有}

使用场景示例

// 场景:定义"飞行能力"// ✅ 用接口:因为飞行是一种能力,不是本质publicinterfaceFlyable{defaultvoidfly(){System.out.println("默认飞行方式");}}// 场景:定义"学生"的基础属性// ✅ 用抽象类:因为学生是本质,有共同的状态和行为publicabstractclassAbstractStudent{privateStringname;// 状态privateintage;publicAbstractStudent(Stringname,intage){this.name=name;this.age=age;}publicvoidsleep(){// 具体行为System.out.println(name+" is sleeping");}publicabstractvoidstudy();// 抽象行为}

组合使用示例

// 抽象类:定义本质 + 共享状态publicabstractclassAbstractStudent{protectedStringname;publicAbstractStudent(Stringname){this.name=name;}publicabstractvoidstudy();}// 接口:定义能力publicinterfaceFlyable{defaultvoidfly(){System.out.println("飞行");}}publicinterfaceSwimable{defaultvoidswim(){System.out.println("游泳");}}// 具体类:继承抽象类 + 实现多个接口publicclassSuperStudentextendsAbstractStudentimplementsFlyable,Swimable{publicSuperStudent(Stringname){super(name);}@Overridepublicvoidstudy(){System.out.println(name+" 正在学习");}}

四、选择建议

场景推荐
需要定义多个不相关类的共同行为用接口
需要共享状态(成员变量)用抽象类
需要多继承只能用接口
需要构造方法初始化用抽象类
只是定义能力/契约用接口
是一种本质/身份用抽象类

五、总结

关键要点

  1. 普通类实现接口:必须实现所有抽象方法,否则编译报错
  2. 抽象类实现接口:可以只实现部分方法
  3. Java 8 default 方法:让接口可以提供默认实现,增强向后兼容性
  4. 接口 vs 抽象类
    • 接口 = 契约 + 能力(能做什么)
    • 抽象类 = 本质 + 模板(是什么,共享状态和行为)

一句话总结

Java 8 的 default 方法只是让接口更灵活,并没有改变接口"定义能力"的本质。如果需要共享状态和构造逻辑,还是要用抽象类。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 8:23:12

AMD Ryzen 硬件调试实战:从零掌握SMUDebugTool的精准控制系统

AMD Ryzen 硬件调试实战:从零掌握SMUDebugTool的精准控制系统 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目地址: htt…

作者头像 李华
网站建设 2026/4/18 8:21:02

WebPlotDigitizer:如何快速从科研图表中提取数据的终极指南

WebPlotDigitizer:如何快速从科研图表中提取数据的终极指南 【免费下载链接】WebPlotDigitizer Computer vision assisted tool to extract numerical data from plot images. 项目地址: https://gitcode.com/gh_mirrors/we/WebPlotDigitizer 在科研工作中&a…

作者头像 李华
网站建设 2026/4/18 8:20:42

解决Tkinter和Matplotlib的无限循环问题

在使用Python进行图形界面编程时,经常会遇到将Matplotlib的图表嵌入到Tkinter窗口中的需求。然而,这个过程中可能会遇到一些棘手的问题,比如程序进入无限循环,导致无法正常结束进程。今天我们就来详细讨论一下这个问题,并通过实例展示如何解决。 问题背景 在编写Tkinter…

作者头像 李华
网站建设 2026/4/18 8:20:03

26-4-17 数据结构作业:用栈解决迷宫问题

1.问题描述 已知一个 66 的迷宫,可将其视作在一个坐标系中,令起点 (1,1),终点 (4,4),墙:1、路:0,要求用队列实现最短路径搜索。 2.算法思路 题目要求使用队列(先进先出&#xff09…

作者头像 李华
网站建设 2026/4/18 8:19:40

解决MVC Web API中的级联保存问题

在开发MVC Web API应用时,处理模型之间的关系是一个常见的挑战,尤其是在使用Entity Framework时。今天我们来探讨一个具体的案例,分析为什么在添加城市数据时,用户数据也会被意外保存到数据库中,并提供解决方案。 案例背景 假设我们有一个城市管理系统,包含以下模型: …

作者头像 李华
网站建设 2026/4/18 8:19:11

戴尔G15散热控制终极指南:开源工具TCC-G15完全解析

戴尔G15散热控制终极指南:开源工具TCC-G15完全解析 【免费下载链接】tcc-g15 Thermal Control Center for Dell G15 - open source alternative to AWCC 项目地址: https://gitcode.com/gh_mirrors/tc/tcc-g15 还在为戴尔G15笔记本的过热降频问题烦恼吗&…

作者头像 李华