当前位置: 首页 > news >正文

【Java基础|Day12】Java接口详解:从入门到实战

文章目录

  • 📚 今日学习目标
  • 一、 为什么需要接口?
  • 二、接口概述
    • 2.1 接口的定义
    • 2.2 接口、类之间的关系
  • 三、接口、抽象类和多态
  • 四、 综合案例

📚 今日学习目标

  1. 理解接口存在的意义
  2. 掌握接口的定义语法,包括其成员变量、成员方法的特点。
  3. 理清接口、类、抽象类三者之间的关系。
  4. 深入对比抽象类与接口,理解它们各自的设计意图和使用场景。
  5. 能够通过实际案例,综合运用抽象类和接口进行程序设计。

一、 为什么需要接口?

🧐 想象一下,我们有三个类:兔子、青蛙 和 狗。

  • 兔子类:会吃饭()、喝水()
  • 青蛙类:会吃饭()、喝水()、游泳()
  • 狗类:会吃饭()、喝水()、游泳()

你会如何设计?

  1. 提取共同点:设计一个父类 动物类 ,包含 吃饭() 和 喝水() 方法。因为所有动物都需要吃饭和喝水。
  2. 问题:那么,游泳() 方法能否也放在 动物类 父类中呢?
    答案是否定的。因为并非所有动物都会游泳(比如兔子),如果强行放入,兔子类在继承后就会获得一个它不应该拥有的“游泳”能力,这不符合现实逻辑。
  3. 现有方案的局限:如果我们将游泳()这个方法各自写在青蛙和狗类中,虽然能解决问题,但会带来新的挑战:
    • 如何使用多态?我们无法用一个统一的类型来操作所有会游泳的动物。
    • 如何统一规范?不同的程序员可能会写出swim()、swimming()、doSwim()等不同的方法名,造成混乱。

💡接口:完美的解决方案

接口可以定义一组行为规范(“能做什么”),而不关心具体的实现细节。

我们可以定义一个游泳接口,它只声明“会游泳”这个行为。然后,让青蛙类和狗类去实现这个接口,并根据自身特点来具体实现游泳()方法。这样,我们就可以利用多态,通过接口引用来调用游泳()方法,产生不同的行为。


二、接口概述

2.1 接口的定义

接口使用关键字interface来定义。它定义了一套行为规范,有以下几个特点:

  1. 成员变量:只能是常量
    • 默认修饰符:public static final(可以省略不写)。
    • 为什么?
      • static:让变量归属于接口,由所有实现类共享,避免了像C++中“菱形继承”可能带来的问题。
      • final:保证常量的不可变性,提供一组公共、统一的规范值。
      • 存在意义:即使没有构造函数,这些常量也有意义。它们为所有实现类提供了可直接使用的、统一的配置或标识,避免了重复定义,方便统一管理。

final 知识点
final 表示“不可变”。

  • final 修饰类:该类不能被继承。
  • final 修饰方法:该方法不能被重写。
  • final 修饰变量:
    • 基本数据类型:变量的值不能被修改。
    • 引用数据类型:变量的地址值不能被修改(即不能再指向其他对象,但对象内部的内容可以改变)。
  1. 构造方法:没有

    • 原因:接口不能被实例化,它的核心是定义行为规则,而不是创建对象。
  2. 成员方法:在JDK 8之前,只能是抽象方法

    • 默认修饰符:public abstract(可以省略不写)。
    • 多态的根源:正是由于接口方法的抽象性,我们才能通过接口引用指向不同实现类的对象,调用时产生不同的行为,这是多态的基础。
  3. 实例化:接口不能被实例化

  4. 实现关系:接口和类是实现关系,通过 implements 关键字表示

    • 实现类必须重写接口中的全部抽象方法。(包括接口的父类中的抽象方法)
    • 如果实现类是抽象类,则可以选择不重写。

2.2 接口、类之间的关系

  • 类和类继承关系,使用 extends。Java中是单继承,但支持多层继承。
  • 类和接口实现关系,使用 implements。Java支持单实现,也支持多实现(一个类可以实现多个接口)。一个类还可以在继承一个父类的同时,实现多个接口。
  • 接口和接口继承关系,使用 extends。可以单继承,也可以多继承。

💡 思考小场景:
如果一个类实现了多个接口,而这些接口中存在相同的抽象方法,会发生什么?
答案:类在实现时,只需要重写这个方法一次,这一次重写就同时满足了多个接口重写的要求。


三、接口、抽象类和多态

  1. 多态的实现基础
    抽象类和接口都是实现多态的重要基础。多态成立,必须存在继承(extends)或实现(implements)关系。
  • 抽象类的多态:继承 + 重写 + 父类引用指向子类对象
  • 接口的多态:实现 + 重写 + 接口引用指向实现类对象
  1. 抽象类vs接口
对比维度抽象类 (Abstract Class)接口 (Interface)
定义关键字abstract classinterface
成员变量可以有各种类型的字段(实例/静态,final/非final,任意访问修饰符)只能有public static final常量(隐式)
构造方法可以有(供子类调用,用于初始化父类字段)不能有
抽象方法使用abstract关键字声明,子类必须实现(除非子类也是抽象类)默认就是public abstract(可省略),实现类必须实现(除非实现类是抽象类)
具体方法可以有(有方法体,任意访问修饰符)JDK 8后可以有defaultstatic方法,但传统上不包含实例具体方法
访问修饰符方法:publicprotected、包级私有、private
变量:任意修饰符
方法:隐式publicdefault/static方法也是public
变量:只能是public
实例化不能,子类要么重写全部抽象方法要么是抽象类不能,实现类要么重写全部抽象方法要么是抽象类
继承/实现限制单继承多实现
多态使用方式抽象类引用指向子类对象,调用重写的方法接口引用指向实现类对象,调用实现的方法
设计意图(语义)“is-a”关系:子类是父类的一种特殊化 强调本质归属代码复用,回答“它是什么”。“can-do”关系:实现类具备某种能力 强调行为契约多角色组合,回答“它能做什么”。
  • 抽象类:抽象的是“事物的本质”,是对一类事物共同特征的提炼,它回答的是 “它是什么”。父类拥有的变量和方法,子类一定拥有,强调子类是父类的一种。
  • 接口:抽象的是“事物的能力”。是对一种行为或角色的规范,它回答的是 “它能做什么”。用来表达跨类别的共同能力,多个不同的类的共同的能力。例如,“会飞”既可以应用于鸟,也可以应用于飞机、超人。

四、 综合案例

场景:我们需要设计一个体育管理系统,涉及以下四种角色:

  • 乒乓球运动员:有姓名、年龄,会学打乒乓球,会说英语。

  • 篮球运动员:有姓名、年龄,会学打篮球。

  • 乒乓球教练:有姓名、年龄,会教打乒乓球,会说英语。

  • 篮球教练:有姓名、年龄,会教打篮球。

设计步骤

  1. 提取共性(“是什么”)
    所有角色都是“人”,有共同的属性:姓名、年龄
    → 创建一个父类 Person,封装这些共有属性和构造方法。
  2. 区分角色类型(“是什么”的细化)
    角色可以细分为“运动员”和“教练”。他们有各自独特的行为(“学习” vs “教授”)。
    → 创建两个抽象类 Athlete 和 Coach,分别继承 Person。在 Athlete 中声明抽象方法 learn(),在 Coach 中声明抽象方法 teach()。这样,所有运动员都必须实现自己的learn()方式,所有教练都必须实现自己的teach()方式。
  3. 处理附加能力(“能做什么”)
    “说英语”这个能力,只有乒乓球相关的角色(运动员和教练)需要,篮球相关的不需要。这是一种跨类别(运动员和教练)的附加能力。
    → 创建一个接口 EnglishSpeakable,在其中定义 speakEnglish() 方法。然后,让PingPongAthlete和PingPongCoach类去实现这个接口,而BasketballAthlete和BasketballCoach则不需要。

以上为个人学习总结,旨在梳理个人理解。如有疏漏或不当之处,欢迎指正与交流。

http://www.jsqmd.com/news/524474/

相关文章:

  • 8.11.3 LangChain 前端(assistant-ui)
  • 探秘 120#西门子 S7 - 200PLC 和组态王的加工站传送包装站控制系统
  • # Array Game
  • AI写标书7天消费冲榜,人人有奖!
  • 从像素到策略:基于循环世界模型的强化学习进化之路
  • 跨平台 Docker 安装指南:Windows、WSL2、Ubuntu 与 macOS
  • 2026年 双桶/多桶磁力去毛刺机厂家推荐榜单:高效精密抛光,工业表面处理技术实力与创新应用深度解析 - 品牌企业推荐师(官方)
  • Python后台任务不中断:nohup与输出缓冲的实战技巧
  • 用Arnis在Minecraft中重建真实地点,体验高细节世界!
  • 2026嘉兴保温砂浆优质品牌推荐指南:嘉兴ftc变相保温材料/嘉兴保温砂浆墙面/嘉兴保温砂浆聚合物/嘉兴保温砂浆防水/选择指南 - 优质品牌商家
  • NE2A-SCPU01安全网络控制器
  • Tiny WS2812:极简跨平台LED驱动库原理与实践
  • 如何在Java中使用字符串拼接优化性能
  • SPM新手避坑指南:手把手教你完成fMRI数据预处理(从DICOM到平滑)
  • IDEA插件Apipost-Helper实战:5分钟搞定SpringBoot接口调试与文档生成
  • 【洛谷刷题 | 第六天】
  • (二)传统企业vs数字原生企业:差距到底在数据,还是思维?
  • 为什么嵌入式开发离不开C语言:底层执行模型与工程实践
  • 我把 VS Code 里看依赖版本的插件,做了一个更快的版本
  • 20252403实验一《Python程序设计》实验报告
  • FPGA千兆网硬件设计避坑指南:RTL8211EG布局布线实战经验分享
  • Prophet实战:如何用Python预测电商促销季的销量波动(附完整代码)
  • Dify Rerank性能翻倍实录:从0.42到0.89 NDCG提升,我们只改了这4行配置
  • Make构建系统原理与嵌入式工程实践
  • 新手必看:Qwen-Image-Edit-2511-Unblur-Upscale修复模糊人像全流程详解
  • RV1126准备-----编译和测试SDK自带的RKNN例程
  • 2026年 隔离式洗衣机厂家推荐排行榜,医用/无尘/消毒/双扉洗衣机,专业洁净与高效隔离技术深度解析 - 品牌企业推荐师(官方)
  • Linux 网卡名称详解:从 lo 到 docker0,一篇搞懂所有网络接口
  • 三月第三周周报
  • CCMusic硬件加速:FPGA实现Mel频谱特征提取