[Java学习日记07】聊聊接口和抽象类

前言:关于"套娃"代码的终极拷问

坐标:图书馆 5 楼(靠空调位,今天风很大)

状态:刚改完一个被无限层级继承搞崩的 Bug。

碎碎念: 兄弟们,今天我彻底破防了。 本来想给我的项目加个新功能,结果发现原作者(也就是上个月的我)写了一堆深不见底的继承。我想改个方法,结果十几个子类全报错。 学长过来看了一眼,摇摇头说:"你这设计,属于是'过度继承',这种场景你应该用接口(Interface)而不是抽象类(Abstract Class)啊。"

回来后我反思了很久。原来这两者虽然都能用来"被继承",但底层逻辑完全不同。今天咱就来聊聊这两大"模板",看看它们到底怎么选!

🚀 目录

  1. [抽象类 (Abstract Class):未完成的"毛坯房"](#抽象类 (Abstract Class):未完成的“毛坯房”)

    • 1.1 什么是抽象类?

    • 1.2 它是为了"共性"而生

  2. [接口 (Interface):一份必须遵守的"协议"](#接口 (Interface):一份必须遵守的“协议”)

    • 2.1 什么是接口?

    • 2.2 它是为了"扩展"而生

  3. 核心对撞:一张表分胜负

  4. [哲学思考:is-a 与 has-a 的博弈](#哲学思考:is-a 与 has-a 的博弈)

    • 4.1 抽象类是"亲爹"

    • 4.2 接口是"考证"

  5. [JDK 8 之后的"叛变":接口居然能写实现了?](#JDK 8 之后的“叛变”:接口居然能写实现了?)

  6. 大厂面试:什么时候该用哪一个?

  7. 结语:代码的优雅在于克制

1. 抽象类 (Abstract Class):未完成的"毛坯房"

生活化场景: 学校要开发一个"学生管理系统"。所有学生(无论是 CS 的、经管的、还是艺术的)都有学号、名字,都要选课。 但不同专业的学生"写作业"的方式完全不一样。

这时候,我们可以搞一个 Student抽象类

1.1 什么是抽象类?

它是一个半成品

  • 它不能被 new 出来(你见过一个纯粹的、没有任何属性的"学生"对象吗?没有,他必须是某个具体的专业生)。

  • 它里面可以有已经写好的方法(大家共用的,比如 sleep()),也可以有没写完的方法(abstract 方法,比如 study())。

1.2 它是为了"共性"而生

抽象类强调的是**"身份(Identity)"**。它是子类的模板,子类是对它的细化。

复制代码
abstract class Student {
    String name;
    
    // 共性方法:大家都得睡觉
    void sleep() {
        System.out.println("在图书馆睡着了...");
    }
    
    // 抽象方法:具体怎么学,子类自己定
    abstract void study();
}

2. 接口 (Interface):一份必须遵守的"协议"

生活化场景: 不论你是学生、老师,还是校外的路人。只要你想进校门,你就得有"进校证(CanEnterSchool)"。 这个证件规定你必须具备"刷码(swipeCard)"和"出示健康信息(showInfo)"的功能。

2.1 什么是接口?

它是一份契约 或者规范

  • 接口只管"能干什么",不管"怎么干"。

  • 它里面全都是没有实现的"大饼"(除非是 JDK 8 以后的 default 方法)。

2.2 它是为了"扩展"而生

接口强调的是**"功能(Ability)"**。一个类可以实现多个接口。

  • 大学生比喻:我可以是一个"学生(抽象类继承)",同时我也可以拥有"英语四级(接口实现)"、"驾照(接口实现)"。

    interface DrivingLicense {
    void drive(); // 只要有驾照,你就得会开车
    }

3. 核心对撞:一张表分胜负

特征 抽象类 (Abstract Class) 接口 (Interface)
关键字 abstract class interface
关系 extends (继承) implements (实现)
数量 单继承(只能有一个亲爹) 多实现(可以考很多证)
变量 可以有普通变量 只能是常量 (public static final)
构造器 (供子类调用)
方法 可以有具体实现,也可以抽象 以前全是抽象,现在可以有 default

4. 哲学思考:is-a 与 has-a 的博弈

这是理解两者的灵魂所在。

4.1 抽象类是"is-a"

如果你觉得 A 是一个 B,那就用抽象类。

  • 是一个 动物。

  • CS学生 是一个 学生。

4.2 接口是"has-a"或"like-a"

如果你觉得 A 具有某种功能,那就用接口。

  • 具有 爬树的能力。

  • 这个类 具有 被序列化的能力(Serializable)。

5. JDK 8 之后的"叛变":接口居然能写实现了?

在很久以前,接口是纯粹的。但从 JDK 8 开始,为了支持 Lambda 表达式和方便版本升级,接口里可以写 default 方法和 static 方法了。

这就尴尬了:接口越来越像抽象类了? 其实不然。即便接口能写实现,它依然没有状态(成员变量) ,依然支持多实现。这些核心本质没变。

6. 大厂面试:什么时候该用哪一个?

面试官最喜欢问:"既然接口现在能写实现,那还要抽象类干嘛?"

你可以这样装杯(回怼)

  1. 如果你需要定义子类的共同属性(比如名字、年龄),抽象类是唯一的选择,因为接口不能存数据(只有常量)。

  2. 如果你需要约束不同类别的行为(比如灯能开关、电视也能开关),请用接口。

  3. 如果你想预留后路,建议用接口。因为 Java 是单继承,用了抽象类就把"亲爹位"占了,以后想改就难了。

7. 结语

写完这篇日记,我终于把之前的"套娃"代码重构完了。 我把那些乱七八糟的继承改成了接口组合,代码瞬间感觉清爽了许多。

作为大学生的我们:

  • 抽象类教我们要有深度(扎实的根基)。

  • 接口教我们要有广度(多样的技能)。

如果你也被"到底用哪个"纠结过,点个赞支持一下!下期咱们聊聊Java的异常体系

相关推荐
Bechamz1 小时前
大数据开发学习Day32
学习
Brilliantwxx1 小时前
【C++】模版进阶(特化+分离编译+非类型模版参数)
开发语言·数据结构·c++·算法
库奇噜啦呼1 小时前
【iOS】源码学习-消息流程分析
学习·ios·cocoa
折哥的程序人生 · 物流技术专研1 小时前
《Java面试85题图解版(三)》上篇:高阶架构设计篇
java·开发语言·后端·面试·职场和发展
枫叶丹41 小时前
【HarmonyOS 6.0】模拟点击检测:鸿蒙6.0全面狙击自动化作弊行为
开发语言·华为·自动化·harmonyos
吴声子夜歌1 小时前
Java——ArrayDeque
java·arraydeque
坚果派·白晓明1 小时前
【鸿蒙PC三方库移植适配框架解读系列】第六篇:关键注意事项与最佳实践
c语言·开发语言·c++·华为·harmonyos·开源鸿蒙
承渊政道1 小时前
【贪心算法】(经典实战应用解析(二):最⻓递增⼦序列、递增的三元⼦序列、最⻓连续递增序列、买卖股票的最佳时机、买卖股票的最佳时机II)
数据结构·c++·学习·算法·leetcode·贪心算法·哈希算法
li星野1 小时前
动态规划十题通关:从爬楼梯到编辑距离(Python + C++)
c++·python·学习·算法·动态规划