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

【Java】抽象类和接口对比+详解

1. 定义与基本语法

抽象类

  • 使用abstract关键字声明
  • 可以包含抽象方法(无实现)和具体方法(有实现)
  • 可以有成员变量、构造方法
  • 子类通过extends关键字继承抽象类,必须实现所有抽象方法

接口

  • 使用interface关键字声明
  • Java 8 之前只能包含抽象方法和常量;Java 8 及以后可以有默认方法(default)和静态方法(static
  • 成员变量默认是public static final(常量)
  • 类通过implements关键字实现接口,必须实现所有抽象方法

2. 核心区别对比

特性抽象类接口
继承方式单继承(一个类只能继承一个抽象类)多实现(一个类可以实现多个接口)
方法类型可以包含抽象方法和具体方法Java 8 后有默认方法和静态方法
成员变量可以有各种类型的成员变量只能是public static final常量
构造方法有构造方法(供子类调用)没有构造方法
访问修饰符可以使用privateprotectedpublic方法默认public,变量默认public static final
使用场景表示 "is-a" 关系,用于抽取类间的共性实现表示 "has-a" 能力,用于定义类的行为规范

3. 示例代码

抽象类示例
// 抽象类 - 表示动物
abstract class Animal {// 成员变量protected String name;// 构造方法public Animal(String name) {this.name = name;}// 抽象方法(无实现)public abstract void makeSound();// 具体方法(有实现)public void eat() {System.out.println(name + "正在吃东西");}
}// 子类继承抽象类
class Dog extends Animal {public Dog(String name) {super(name);}// 必须实现抽象方法@Overridepublic void makeSound() {System.out.println(name + "汪汪叫");}
}class Cat extends Animal {public Cat(String name) {super(name);}@Overridepublic void makeSound() {System.out.println(name + "喵喵叫");}
}public class Test {public static void main(String[] args) {Animal dog = new Dog("阿黄");Animal cat = new Cat("咪咪");dog.makeSound();dog.eat();cat.makeSound();cat.eat();}
}

super(name)的作用是调用父类(Animal类)的构造方法,并将参数name传递给父类的构造方法。

DogCat作为Animal的子类,它们的构造方法中必须通过super(name)显式调用父类的构造方法。这是因为父类Animal定义了带参数name的构造方法,而 Java 规定:当父类没有无参构造方法时,子类构造方法必须在第一行通过super(参数)调用父类对应的有参构造方法,以确保父类的成员变量(如name)能被正确初始化。

通过这种方式,子类创建对象时传入的name会被传递到父类,完成Animal类中name成员变量的赋值,使子类对象能继承并使用该属性(如在makeSound()eat()方法中通过name输出动物名称)。

接口示例
// 接口 - 表示会飞的能力
interface Flyable {// 常量int MAX_HEIGHT = 1000; // 等价于 public static final int MAX_HEIGHT = 1000;// 抽象方法void fly();// 默认方法(Java 8+)default void land() {System.out.println("降落到地面");}// 静态方法(Java 8+)static void showMaxHeight() {System.out.println("最大飞行高度: " + MAX_HEIGHT + "米");}
}// 接口 - 表示会游泳的能力
interface Swimmable {void swim();
}// 类实现多个接口
class Duck extends Animal implements Flyable, Swimmable {public Duck(String name) {super(name);}@Overridepublic void makeSound() {System.out.println(name + "嘎嘎叫");}@Overridepublic void fly() {System.out.println(name + "在天空飞翔");}@Overridepublic void swim() {System.out.println(name + "在水里游泳");}
}

4. 使用场景分析

使用抽象类的情况

  • 多个类共享相同的实现逻辑时(代码复用)
  • 需要定义类的基础行为并为子类提供默认实现
  • 需要包含成员变量和构造方法
  • 表示类之间的继承关系("is-a")

使用接口的情况

  • 定义类的行为规范但不关心具体实现
  • 需要实现多继承的效果(一个类具备多种能力)
  • 作为不同模块之间的契约(API 设计)
  • 表示类具备某种能力("has-a")

5. Java 8+ 接口新特性带来的变化

Java 8 引入的默认方法和静态方法模糊了抽象类和接口的界限,但核心区别依然存在:

  • 接口不能有构造方法和普通成员变量
  • 一个类只能继承一个抽象类,但可以实现多个接口
  • 接口的默认方法可以被实现类重写,而抽象类的具体方法也可以被重写

6. 综合示例

// 抽象类 - 交通工具
abstract class Vehicle {protected String brand;protected int speed;public Vehicle(String brand) {this.brand = brand;this.speed = 0;}// 抽象方法public abstract void accelerate();// 具体方法public void brake() {speed = Math.max(0, speed - 10);System.out.println(brand + "减速,当前速度: " + speed + "km/h");}public void displayInfo() {System.out.println("品牌: " + brand + ", 当前速度: " + speed + "km/h");}
}// 接口 - 可充电
interface Chargeable {int MAX_BATTERY = 100; // 最大电量void charge();default void showBatteryLevel(int level) {System.out.println("当前电量: " + level + "%");}
}// 接口 - 有导航
interface Navigable {void navigate(String destination);
}// 电动汽车 - 继承抽象类并实现多个接口
class ElectricCar extends Vehicle implements Chargeable, Navigable {private int batteryLevel;public ElectricCar(String brand) {super(brand);this.batteryLevel = 50; // 初始电量50%}@Overridepublic void accelerate() {if (batteryLevel > 0) {speed = Math.min(120, speed + 20);batteryLevel = Math.max(0, batteryLevel - 5);System.out.println(brand + "加速,当前速度: " + speed + "km/h");showBatteryLevel(batteryLevel);} else {System.out.println("电量耗尽,无法加速");}}@Overridepublic void charge() {batteryLevel = Math.min(MAX_BATTERY, batteryLevel + 30);System.out.println(brand + "正在充电");showBatteryLevel(batteryLevel);}@Overridepublic void navigate(String destination) {System.out.println("从当前位置导航到: " + destination);System.out.println("预计行驶时间: 30分钟");}
}// 测试类
public class AbstractInterfaceDemo {public static void main(String[] args) {ElectricCar tesla = new ElectricCar("特斯拉Model 3");tesla.displayInfo();tesla.accelerate();tesla.accelerate();tesla.brake();tesla.navigate("中央公园");tesla.charge();}
}

7. 总结

  • 抽象类注重代码复用和继承关系,适合定义类的基础结构
  • 接口注重行为规范和多实现,适合定义类的能力
  • 抽象类是 "是什么",接口是 "能做什么"
  • 在设计时,应优先考虑使用接口,当需要共享代码实现时再考虑抽象类
  • Java 8 + 的接口默认方法使得接口可以提供默认实现,但不会改变接口作为行为规范的本质

文章转载自:

http://aGJ6Zpjy.pLpqf.cn
http://hfMM5JZ2.pLpqf.cn
http://6yHVFrud.pLpqf.cn
http://d3IO7WpQ.pLpqf.cn
http://qL2rnet0.pLpqf.cn
http://tdnZiSIj.pLpqf.cn
http://jibjEf88.pLpqf.cn
http://IrsGzF7Y.pLpqf.cn
http://z5Rg1ijO.pLpqf.cn
http://pPqojwFd.pLpqf.cn
http://yBYlhphj.pLpqf.cn
http://QQHlNz2C.pLpqf.cn
http://g9cwebuA.pLpqf.cn
http://dWfpEhB9.pLpqf.cn
http://MRo0Oxoy.pLpqf.cn
http://KCVqRmP9.pLpqf.cn
http://jM33Pwpp.pLpqf.cn
http://fzkqX0Cj.pLpqf.cn
http://z4iF27qX.pLpqf.cn
http://wPn1akks.pLpqf.cn
http://joIsWleh.pLpqf.cn
http://U0742PEO.pLpqf.cn
http://JyAyImqL.pLpqf.cn
http://NFPD6kST.pLpqf.cn
http://t1iDbSmr.pLpqf.cn
http://9OVA0aei.pLpqf.cn
http://ppeZTxQ4.pLpqf.cn
http://67hajaMS.pLpqf.cn
http://PSH1XiIM.pLpqf.cn
http://3gRPnGQP.pLpqf.cn
http://www.dtcms.com/a/370039.html

相关文章:

  • 校园管理系统|基于SpringBoot和Vue的校园管理系统(源码+数据库+文档)
  • LeetCode5最长回文子串
  • Coze源码分析-资源库-编辑提示词-前端源码
  • 《sklearn机器学习——聚类性能指标》Contingency Matrix(列联表)详解
  • 小米笔记本电脑重装C盘教程
  • Linux RCU (Read-Copy-Update) 机制深度分析
  • 贪心算法应用:柔性制造系统(FMS)刀具分配问题详解
  • WSL Ubuntu Docker 代理自动配置教程
  • 基于Scikit-learn集成学习模型的情感分析研究与实现
  • MySQL数据库精研之旅第十七期:深度拆解事务核心(下)
  • Scikit-learn Python机器学习 - 特征降维 压缩数据 - 特征选择 - 单变量特征选择 SelectKBest - 选择Top K个特征
  • 从挑西瓜到树回归:用生活智慧理解机器学习算法
  • LabVIEW无线预警喷淋系统
  • Redis 的三种高效缓存读写策略!
  • 安装MATLAB205软件记录
  • Day28 打卡
  • 【FastDDS】XTypes Extensions
  • 软考 系统架构设计师系列知识点之杂项集萃(142)
  • 【音视频】H264编码参数优化和cbr、vbr、crf模式设置
  • 软考 系统架构设计师系列知识点之杂项集萃(141)
  • 竞价代运营:百度竞价账户托管优化
  • Python实战:爬取百度热搜榜,制作动态可视化报告
  • Windows 设备音频录制 | WASAPI 音频数据采集 / 环回录制
  • uniapp新增页面及跳转配置方法
  • 西门子S7-200 SMART PLC:编写最基础的“起保停”程序
  • UDP-Server(2)词典功能
  • 最大似然估计:损失函数的底层数学原理
  • 今日分享:C++ -- list 容器
  • 报错:OverflowError: Python integer 4294967296 out of bounds for uint32
  • 贪心算法应用:蛋白质折叠问题详解