第13章 抽象类与接口
第13章 抽象类与接口多态是行为而抽象类与接口是行为规范——先定义规则再让具体类实现。它们是 Java 实现面向抽象编程的两大武器。本节理清两者的区别和使用场景。一、抽象方法父类中的方法子类必须重写父类自己却无法给出具体实现——这时用抽象方法abstractvoidsound();// 没有方法体只有声明抽象方法以分号结束没有大括号。任何含有抽象方法的类必须是抽象类。**为什么需要抽象方法**因为父类不知道该怎么说。动物都要叫但猫叫喵、狗叫汪父类给不出统一实现只能立个规矩谁继承我谁就得自己实现——这就是先定规范、后补细节。// ❌ 抽象方法不能有方法体// abstract void sound() { } // 编译错误abstract 方法不能有大括号一个类可以有多个抽象方法子类必须全部实现abstractclassShape{abstractdoublearea();// 面积每个图形算法不同abstractdoubleperimeter();// 周长每个图形算法不同}classCircleextendsShape{doubler;Circle(doubler){this.rr;}Overridedoublearea(){returnMath.PI*r*r;}Overridedoubleperimeter(){return2*Math.PI*r;}}classSquareextendsShape{doubleside;Square(doubleside){this.sideside;}Overridedoublearea(){returnside*side;}Overridedoubleperimeter(){return4*side;}}System.out.println(newCircle(1).area());// 3.141592653589793System.out.println(newSquare(2).perimeter());// 8.0二、抽象类用abstract修饰的类就是抽象类abstractclassAnimal{Stringname;// 普通方法可以有实现voideat(){System.out.println(name 在吃东西);}// 抽象方法没有实现子类必须重写abstractvoidsound();}classDogextendsAnimal{Overridevoidsound(){System.out.println(汪汪);}}要点抽象类不能 new不能实例化——它是半成品模板抽象类可以有构造器子类创建时调用抽象方法只能定义在抽象类中子类必须实现所有抽象方法否则子类也要声明为抽象类抽象类可以没有抽象方法纯模板类也可以有普通方法、成员变量**为什么抽象类不能 new**因为它可能含有没写完的抽象方法new 出来调用sound()时不知道该执行什么。只能由子类补全后用子类创建对象。抽象类可以有构造器和成员变量子类创建对象时先调用父类构造器abstractclassAnimal{Stringname;Animal(Stringname){// 抽象类可以有构造器this.namename;// 子类 new 的时候会先调用它}abstractvoidsound();}classDogextendsAnimal{Dog(Stringname){super(name);// 显式调用父类构造器}Overridevoidsound(){System.out.println(name汪汪);}}AnimalanewDog(旺财);a.sound();// 旺财汪汪抽象类里的普通方法还可以直接调用抽象方法——这就是多态运行时执行的是子类的实现abstractclassAnimal{voiddescribe(){System.out.print(我是一只动物叫声是);sound();// 调用抽象方法运行时跳到子类的实现}abstractvoidsound();}classCatextendsAnimal{voidsound(){System.out.println(喵喵);}}newCat().describe();// 我是一只动物叫声是喵喵三、接口接口interface比抽象类更纯粹——它只定义行为规范方法签名不关心实现// 定义接口interfaceFlyable{voidfly();// 接口方法默认是 public abstract}interfaceSwimmable{voidswim();}// 类实现接口用 implements可以实现多个classDuckimplementsFlyable,Swimmable{Overridepublicvoidfly(){System.out.println(鸭子会飞);}Overridepublicvoidswim(){System.out.println(鸭子会游泳);}}接口的规则接口中的方法默认是public abstract没有方法体接口中的变量默认是public static final常量一个类可以实现多个接口——弥补 Java 单继承的不足接口不能实例化也没有构造器实现接口的类必须实现所有抽象方法除非是抽象类接口里的变量都是常量用接口名直接访问interfaceConfig{intMAX_SIZE1024;// 等价于 public static final int MAX_SIZE 1024;}System.out.println(Config.MAX_SIZE);// 1024接口本质是能力的清单。同一个类可以实现多个接口把多种能力组合起来interfacePayable{voidpay();}// 能力可支付interfaceRefundable{voidrefund();}// 能力可退款classWeChatPayimplementsPayable,Refundable{Overridepublicvoidpay(){System.out.println(微信支付成功);}Overridepublicvoidrefund(){System.out.println(退款成功);}}接口的默认方法与静态方法JDK 8接口可以有带实现的方法interfaceFlyable{voidfly();// 默认方法实现类可以不改defaultvoidtakeOff(){System.out.println(准备起飞);}// 静态方法用接口名直接调用staticvoidinfo(){System.out.println(这是飞行接口);}}default方法让接口可以平滑增加新方法而不破坏已有实现类——JDK 8 给集合框架加新特性就是靠它。这套机制从 JDK 8 引入后一直保留JDK 11、JDK 17 同样支持只要项目用的 JDK 是 8 或更高版本default 和 static 方法都能放心用。四、典型应用Comparable 排序接口让学生按成绩排序classStudentimplementsComparableStudent{Stringname;doublescore;Student(Stringname,doublescore){this.namename;this.scorescore;}OverridepublicintcompareTo(Studentother){// 负数this 小0相等正数this 大returnDouble.compare(this.score,other.score);}OverridepublicStringtoString(){returnname:score;}}Student[]students{newStudent(张三,85),newStudent(李四,92),newStudent(王五,78)};Arrays.sort(students);// 按成绩升序System.out.println(Arrays.toString(students));// [王五:78.0, 张三:85.0, 李四:92.0]Comparable就是可比较的能力规范Arrays.sort 只认这个接口——这就是面向接口编程。想换排序规则比如按姓名不需要改 Student 类另配一个 Comparator 即可// 匿名内部类写法JDK 8 及以后都支持Arrays.sort(students,newComparatorStudent(){Overridepublicintcompare(Studenta,Studentb){returna.name.compareTo(b.name);// 按姓名排序}});System.out.println(Arrays.toString(students));// [张三:85.0, 李四:92.0, 王五:78.0]// 更简洁的 lambda 写法JDK 8Arrays.sort(students,(a,b)-a.name.compareTo(b.name));五、扩展知识5.1 抽象类 vs 接口对比表这是面试高频题对比表背下来对比项抽象类接口关键字abstract classinterface继承方式extends单继承implements多实现方法可有抽象方法 普通方法抽象方法 default/static 方法成员变量普通变量、常量只有常量构造器有没有本质是什么is-a描述共性能做什么can-do定义能力使用场景一类事物的共性模板跨类别的能力规范会飞、会游泳选择原则想让多个不相关类共享行为规范 → 接口如 Comparable、Runnable类之间是is-a关系且有公共状态/方法实现 → 抽象类如 Animal → Dog优先用接口设计灵活一个类可以实现多个两者不冲突可以搭配用抽象类沉淀公共代码接口补充能力5.2 模板方法模式初识抽象类常用于模板方法模式定义算法骨架细节交给子类abstractclassGame{// 模板方法定义游戏流程骨架publicfinalvoidplay(){start();playRound();end();}abstractvoidstart();abstractvoidplayRound();abstractvoidend();}classChessextendsGame{voidstart(){System.out.println(国际象棋开始);}voidplayRound(){System.out.println(下棋中...);}voidend(){System.out.println(游戏结束);}}newChess().play();// 国际象棋开始// 下棋中...// 游戏结束流程骨架固定具体环节由子类各自实现。再看一个冲饮料的例子它多了个钩子方法子类可以重写它来改变流程走向abstractclassBeverage{// 模板方法流程固定子类不能改finalpublicfinalvoidprepare(){boilWater();brew();pourInCup();if(wantCondiments()){// 钩子方法默认 trueaddCondiments();}}voidboilWater(){System.out.println(烧水);}abstractvoidbrew();voidpourInCup(){System.out.println(倒入杯子);}booleanwantCondiments(){returntrue;}// 钩子默认要加料abstractvoidaddCondiments();}classCoffeeextendsBeverage{voidbrew(){System.out.println(冲泡咖啡粉);}voidaddCondiments(){System.out.println(加糖和牛奶);}}classTeaextendsBeverage{voidbrew(){System.out.println(冲泡茶叶);}voidaddCondiments(){System.out.println(加柠檬);}OverridebooleanwantCondiments(){returnfalse;}// 纯茶不加料}newCoffee().prepare();// 烧水// 冲泡咖啡粉// 倒入杯子// 加糖和牛奶5.3 接口的多继承能力随意组合Java 的类只能单继承但接口可以继承接口规范可以层层叠加interfaceWalkable{voidwalk();}interfaceJoggingextendsWalkable{voidjog();}// 接口继承接口规范叠加// 实现 Jogging 的类walk() 和 jog() 都要实现classRobotimplementsJogging{publicvoidwalk(){System.out.println(机器人走路);}publicvoidjog(){System.out.println(机器人慢跑);}}再配合一个类可实现多个接口就能像搭积木一样组合多种能力比层层继承类灵活得多。5.4 sealed限制继承名单JDK 17默认情况下任何类都能继承你的类。有些业务希望只有这几个子类其他人不许继承——JDK 17 的sealed正好解决这个问题// 需 JDK 17 才能运行sealedinterfaceShapepermitsCircle,Square{}finalclassCircleimplementsShape{}finalclassSquareimplementsShape{}// class Triangle implements Shape {} // 编译错误不在 permits 名单里适用场景支付方式只有微信、支付宝、银行卡三种订单状态只有待支付、已支付、已取消——这类枚举式的继承范围用 sealed 约束最合适。JDK 8、JDK 11 不支持此写法只有 JDK 17 能运行初学了解即可。六、易错点易错 1抽象类不能直接 new// ❌ 编译错误抽象类不能实例化// Animal a new Animal();// ✅ 用子类对象父类引用指向它AnimalanewDog(旺财);易错 2子类没实现全部抽象方法// ❌ 编译错误Dog 没实现 sound()自己又不是抽象类// class Dog extends Animal { }// ✅ 要么实现全部抽象方法……classDogextendsAnimal{Dog(Stringname){super(name);}voidsound(){System.out.println(汪汪);}}// ✅ ……要么自己也声明成抽象类但这样 Dog 还是不能 new// abstract class Dog extends Animal { }易错 3接口方法忘记实现// ❌ 编译错误Duck 没有实现 fly()// class Duck implements Flyable { }// ✅ 实现接口的所有抽象方法classDuckimplementsFlyable{publicvoidfly(){System.out.println(鸭子飞);}}// 注意接口方法默认是 public实现时也要写 public易错 4default 方法多接口冲突interfaceA{defaultvoidhello(){System.out.println(A);}}interfaceB{defaultvoidhello(){System.out.println(B);}}// ❌ 编译错误C 同时继承了两个同名 default 方法必须自己解决// class C implements A, B { }// ✅ 重写并在方法里明确指定调用哪一个classCimplementsA,B{Overridepublicvoidhello(){A.super.hello();// 明确调用 A 的默认方法}}newC().hello();// A易错 5认为抽象类必须有抽象方法// ❌ 误区抽象类必须至少有一个抽象方法// ✅ 事实抽象类可以全是普通方法照样合法abstractclassTemplate{voidstep1(){System.out.println(第一步);}voidstep2(){System.out.println(第二步);}}// 它的作用仅仅是禁止 new只能被继承子类直接复用这些普通方法七、小结抽象方法只有声明没有实现含抽象方法的类必须声明为抽象类抽象类不能 new可以有构造器、普通方法、成员变量子类必须实现所有抽象方法接口是纯规范方法默认 public abstract变量默认 public static final一个类可实现多个接口抽象类描述是什么接口描述能做什么优先用接口JDK 8 起接口支持 default 和 static 方法JDK 17 起可用 sealed 限定继承名单模板方法模式抽象类定骨架final 模板方法 钩子方法子类填细节下一节学习 String 与 StringBuilder。下一篇第14章 String 与 StringBuilder

相关新闻

线性规划入门:Python与MATLAB实战,从建模到求解全解析

线性规划入门:Python与MATLAB实战,从建模到求解全解析

1. 项目概述:为什么线性规划是数学建模的“第一块积木”如果你刚开始接触数学建模,或者正准备参加亚太杯、国赛这类竞赛,面对一堆算法名词感到无从下手,那我建议你从“线性规划”开始。这不是因为它最简单——虽然它的核心思想确实…

2026/8/22 12:48:03 阅读更多 →
PROFINET与以太网:从协议差异到工业通信故障排查实战

PROFINET与以太网:从协议差异到工业通信故障排查实战

最近在调试一个工业设备时,遇到了一个让我思考良久的问题:一个基于PROFINET的从站设备,明明物理链路是通的,但控制器就是死活“看”不到它。排查了半天,最后发现是设备制造商在GSDML文件中,将一个关键模块的…

2026/8/21 12:41:50 阅读更多 →
gradle-docker 双客户端架构深度解析:Native 二进制 vs docker-java 如何选型?

gradle-docker 双客户端架构深度解析:Native 二进制 vs docker-java 如何选型?

gradle-docker 双客户端架构深度解析:Native 二进制 vs docker-java 如何选型? 【免费下载链接】gradle-docker A Gradle plugin to build Docker images from the build script. 项目地址: https://gitcode.com/gh_mirrors/gra/gradle-docker gr…

2026/8/21 12:40:50 阅读更多 →

最新新闻

AI 导出鸭革新转换思路,轻松搞定 deepseek 的表格怎么导出使用痛点

AI 导出鸭革新转换思路,轻松搞定 deepseek 的表格怎么导出使用痛点

一、项目核心痛点与市场需求 当下财会、科研、市场调研从业者普遍依靠DeepSeek生成统计表格、调研数据表,在日常办公场景里最突出的难题就是模型生成的表格仅内嵌在对话纯文本中,无法直接保存为Word可用表格格式。 从小微企业财务岗调研视角来看&#xf…

2026/8/22 15:40:23 阅读更多 →
Normy × RTK Query实战:一行createNormalizationMiddleware中间件搞定缓存自动更新

Normy × RTK Query实战:一行createNormalizationMiddleware中间件搞定缓存自动更新

Normy RTK Query实战:一行createNormalizationMiddleware中间件搞定缓存自动更新 【免费下载链接】normy Automatic normalization and data updates for data fetching libraries (react-query, vue-query, trpc, swr, rtk-query and more) 项目地址: https://g…

2026/8/22 15:40:23 阅读更多 →
百度网盘秒传链接快速转存网页工具:单条30秒入库,批量一次搞定

百度网盘秒传链接快速转存网页工具:单条30秒入库,批量一次搞定

百度网盘秒传链接快速转存网页工具:单条30秒入库,批量一次搞定 【免费下载链接】baidupan-rapidupload 百度网盘秒传链接转存/生成/转换 网页工具 (全平台可用) 项目地址: https://gitcode.com/gh_mirrors/bai/baidupan-rapidupload baidupan-rap…

2026/8/22 15:40:23 阅读更多 →
OBS 多RTMP同时配信插件完全指南:一次编码,推流多个平台

OBS 多RTMP同时配信插件完全指南:一次编码,推流多个平台

OBS 多RTMP同时配信插件完全指南:一次编码,推流多个平台 【免费下载链接】obs-multi-rtmp OBS複数サイト同時配信プラグイン 项目地址: https://gitcode.com/gh_mirrors/ob/obs-multi-rtmp obs-multi-rtmp 是一款免费开源的 OBS 多平台同时推流插…

2026/8/22 15:40:23 阅读更多 →
backtrader-pyqt-ui完整指南:5分钟跑通可视化量化回测的策略回测

backtrader-pyqt-ui完整指南:5分钟跑通可视化量化回测的策略回测

backtrader-pyqt-ui完整指南:5分钟跑通可视化量化回测的策略回测 【免费下载链接】backtrader-pyqt-ui 项目地址: https://gitcode.com/gh_mirrors/bac/backtrader-pyqt-ui 先拿一个具体任务说话:验证双均线策略在日线数据上到底有没有效。你不用…

2026/8/22 15:40:23 阅读更多 →
Beat Link Trigger 开发者指南:Clojure 项目架构、Leiningen 构建流程与社区贡献入门

Beat Link Trigger 开发者指南:Clojure 项目架构、Leiningen 构建流程与社区贡献入门

Beat Link Trigger 开发者指南:Clojure 项目架构、Leiningen 构建流程与社区贡献入门 【免费下载链接】beat-link-trigger Trigger events and automate shows in response to events on Pioneer CDJs 项目地址: https://gitcode.com/gh_mirrors/be/beat-link-tri…

2026/8/22 15:39:23 阅读更多 →

日新闻

沉金PCB工艺实战指南:从设计到SMT焊接的可靠性保障

沉金PCB工艺实战指南:从设计到SMT焊接的可靠性保障

在电子硬件开发领域,PCB(印制电路板)的沉金工艺是提升产品可靠性和焊接质量的关键环节。对于需要高密度互连、长期稳定运行或高频信号传输的板卡,如“黍姐仿通行证”这类可能涉及身份识别、数据交互的硬件项目,选择正确…

2026/8/22 0:00:11 阅读更多 →
电气考研电路八月强化四步法:从知识体系到真题实战的闭环攻略

电气考研电路八月强化四步法:从知识体系到真题实战的闭环攻略

这次我们来看一个针对电气考研电路科目的学习规划项目。它不是软件工具,而是一套聚焦于8月份关键节点的备考策略。对于电气工程考研的同学来说,电路分析是专业课的重中之重,也是拉开分差的关键。进入8月,复习进入强化阶段&#xf…

2026/8/22 0:00:11 阅读更多 →
消除AI代码的“AI味”:Claude Code设计优化技能配置与实战指南

消除AI代码的“AI味”:Claude Code设计优化技能配置与实战指南

大家好,我是专注于前端开发与AI工具实践的技术博主。在日常使用 Claude Code 等AI编程助手时,你是否也遇到过这样的困扰:生成的代码功能上没问题,但代码风格、组件设计、交互逻辑总透着一股“AI味”——布局单调、样式简陋、交互生…

2026/8/22 0:00:11 阅读更多 →

周新闻

基于阿里云与通义千问(Qwen)构建AI应用:从模型调用到生产部署的完整实践指南

基于阿里云与通义千问(Qwen)构建AI应用:从模型调用到生产部署的完整实践指南

如果你是一名开发者,最近可能已经感受到了AI大模型正在从“玩具”变成“生产力工具”的强烈信号。从代码补全到智能Agent,从本地部署到云端API,我们正处在一个技术栈快速重构的节点。然而,面对层出不穷的模型、框架和工具&#xf…

2026/8/21 3:21:33 阅读更多 →
工业通信系统底层逻辑:04 反射——高频能量撞墙之后会发生什么?

工业通信系统底层逻辑:04 反射——高频能量撞墙之后会发生什么?

第四篇:反射——高频能量撞墙之后会发生什么? —— 你以为信号已经过去了,其实它正在回来打你 老Q的现场笔记 第五季,我们正式进入工业神经系统层。这里不再是单个设备的战斗,而是整个工厂“经脉”层面的秩序之战。从这一篇开始,你将第一次看清:看似简单的信号传播,背…

2026/8/22 8:09:09 阅读更多 →
【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码

【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码

✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。🍎 往期回顾关注个人主页:Matlab科研工作室👇 关注我领取海量matlab电子书和…

2026/8/21 6:07:56 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/21 16:42:28 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/22 7:31:03 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/22 3:22:48 阅读更多 →