[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的异常体系

相关推荐
yuniko-n几秒前
【Java】字符串相关坑点
java·开发语言·python
m4Rk_几秒前
【论文阅读】Agent 记忆机制(91):THEANINE——不删除过时记忆,让 Agent 记住事情是如何变化的
论文阅读·人工智能·学习·开源·github
Terra.K2 分钟前
Spring AI day1(SSE+AI)
java·人工智能·spring·springai
斑鸠喳喳4 分钟前
线程本地存储 ThreadLocal
java·后端
我命由我1234523 分钟前
Photoshop - Photoshop 面板和菜单
学习·职场和发展·产品运营·求职招聘·职场发展·产品经理·photoshop
jimy127 分钟前
虚函数vtable,链接时看到构造函数,linker把符号地址写入vtable(三)
开发语言·c++
ss27330 分钟前
AI全栈实战 | 3.3-02 Python 并发:有 GIL 为什么还用多线程,asyncio 和 JS 事件循环同源不同味
开发语言·javascript·python
菜鸟~noob23334 分钟前
【电子战】第20篇:凸优化与对数障碍法【含matlab代码】
开发语言·matlab
一木 之林38 分钟前
RAG开发学习总结:从 LangChain 入门到检索增强生成链路的全栈实战-4/6
人工智能·学习·计算机视觉·langchain
LHR_friendship39 分钟前
HCIP课程全部内容
网络·笔记·学习·hcip·华为ensp