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

相关推荐
2601_9669496511 小时前
如何根据研究的起止时间截取分钟级行情?Python 实战与 QuantDash 数据处理指南
开发语言·python·pandas·量化交易·1024程序员节·股票数据·quantdash
晨曦中的暮雨13 小时前
限流算法——固定窗口、滑动窗口、漏桶、令牌桶
java·开发语言·算法
喵了几个咪13 小时前
GoWind CMS 拆解:在 Go 里给 TipTap 搭一套 Yjs 协同后端
开发语言·后端·golang
程序员清风13 小时前
数据处理脚本工程化:日志、配置、命令行与测试
服务器·开发语言·数据库
学长毕设14 小时前
基于SpringBoot的青少年编程学习平台系统-附源码
spring boot·学习·青少年编程
文丑颜不良啊14 小时前
LeetCode876~900题目解析
java·leetcode
aloha_78915 小时前
Java 基础、集合、异常与 JUnit 5 速查
java·junit·sqlserver
知守观15 小时前
设计模式实战:从真实老项目中看标准模板方法与工厂的落地
java·spring·设计模式
2601_9628857215 小时前
如何用 Python 把 K 线重采样成任意周期?
开发语言·python
独隅15 小时前
Claude API 实战教程:从入门到完整项目
android·java·数据库·claude·claude code