抽象类与接口的区别
抽象类和接口时 Java中实现抽象逻辑的两种重要机制,它们都用于定义规范并隐藏具体实现,但在设计目的和使用场景上有显著区别。
详细解析:
1.关键字不同
2.定义与继承/实现方式
(1)抽象类:
用abstract class定义,子类通过extends继承,且Java中类只能单继承(一个子类最多继承一个抽象类)。
abstract class Animal { // 抽象类public abstract void eat(); // 抽象方法(无实现)public void breathe() { // 具体方法(有实现)System.out.println("呼吸");}
}class Dog extends Animal { // 单继承@Overridepublic void eat() {System.out.println("狗吃骨头");}
}
(2)接口:
用interface定义,类通过implements实现,一个类可以同时实现多个接口(多实现)。
interface Flyable { // 接口void fly(); // 抽象方法(默认public abstract)
}interface Runnable {void run();
}class Bird implements Flyable, Runnable { // 多实现@Overridepublic void fly() {System.out.println("鸟飞");}@Overridepublic void run() {System.out.println("鸟跑");}
}
3.方法与字段的差异
(1)抽象类:
- 可以混合抽象方法(
abstract
修饰,无实现)和具体方法(有方法体)。 - 字段可以是任意访问修饰符(
private
/protected
/public
),可以是变量(可修改)或常量。
abstract class Car {protected String brand; // 普通字段(可修改)private static final int WHEEL_COUNT = 4; // 常量public abstract void drive(); // 抽象方法public void honk() { // 具体方法System.out.println("鸣笛");}
}
(2)接口:
- Java 8 前:只能有抽象方法(默认
public abstract
,无需显式声明)。 - Java 8 后:可添加
default
方法(有实现,供实现类直接使用或重写)和static
方法(接口的静态工具方法)。 - 字段默认是
public static final
(必须初始化,且不能修改)。
interface Chargeable {int MAX_POWER = 100; // 等价于 public static final int MAX_POWER = 100void charge(); // 抽象方法(默认public abstract)default void showPower() { // 默认方法(有实现)System.out.println("当前功率:" + MAX_POWER);}static void safetyTips() { // 静态方法System.out.println("充电安全提示");}
}
4.构造方法与实例化
(1)抽象类
有构造方法(用于子类初始化时调用),但不能直接实例化(需通过子类实例化)
abstract class Shape {public Shape() { // 构造方法System.out.println("创建形状");}
}class Circle extends Shape {public Circle() {super(); // 调用父类构造方法}
}// 错误:不能实例化抽象类
// Shape shape = new Shape();
(2)接口:无构造方法,绝对不能实例化(接口时规范,不是具体实现)
4.设计目的与使用场景
(1)抽象类:核心是代码复用。
例如:Animal
是抽象类,Dog
、Cat
是其子类(狗和猫 “是” 动物),抽象类中可包含所有动物的 共性方法(如 breathe()
),子类只需实现自己特有的方法(如 eat()
)。
(2)接口:核心是定义规范。
例如:Flyable
接口定义 “飞” 的规范,Bird
(鸟)、Plane
(飞机)都可以实现 Flyable
—— 它们不是同一类事物,但都 “能飞”。