Skip to content
第 8 章 后端 ⏱ 12 分钟阅读

第 8 章:抽象类与接口 ​

学习目标 ​

  • 理解抽象类和接口的本质区别
  • 掌握 abstract / interface / implements 关键字
  • 学会选择:什么时候用抽象类,什么时候用接口

一、抽象类(abstract) ​

抽象类 = 不能实例化、专门用来被继承的类。

java
public abstract class Shape {
    public abstract double area();         // 抽象方法:只有声明,没有实现

    public void printInfo() {              // 普通方法:可以有实现
        System.out.println("面积:" + area());
    }
}

// Shape s = new Shape();   // ❌ 不能实例化抽象类

子类必须实现所有抽象方法(除非子类也是抽象类):

java
public class Circle extends Shape {
    private double radius;

    public Circle(double radius) { this.radius = radius; }

    @Override
    public double area() {                  // 必须实现父类的抽象方法
        return Math.PI * radius * radius;
    }
}

二、接口(interface) ​

接口 = 行为的抽象(能力清单)。Java 8+ 支持默认方法和静态方法。

java
public interface Flyable {
    int MAX_HEIGHT = 10000;              // 隐式 public static final
    void fly();                          // 隐式 public abstract(必须实现)

    default void land() {                // Java 8+:默认方法(可不实现)
        System.out.println("降落");
    }

    static boolean canFly(Flyable f) {   // Java 8+:静态方法
        return f != null;
    }
}

类用 implements 实现接口,可多实现:

java
public class Bird implements Flyable {
    @Override
    public void fly() {
        System.out.println("鸟在飞");
    }
}

public class Duck implements Flyable, Swimmable, Runnable {  // 多实现
    @Override public void fly() { }
    @Override public void swim() { }
    @Override public void run() { }
}

三、抽象类 vs 接口(怎么选) ​

维度抽象类接口
关键字abstract classinterface
继承/实现单继承(extends)多实现(implements)
字段可以是任何字段只能是 public static final
方法抽象+普通+构造器抽象+默认+静态(JDK 8+)
设计意图"是什么"(is-a)"能做什么"(has-a)

选择规则:

java
// ✅ 抽象类:同一类族的共性(如 Animal → Dog/Cat)
abstract class Animal { abstract void sound(); }
class Dog extends Animal { ... }

// ✅ 接口:跨类族的共同能力(如 Bird / Airplane 都能 Fly)
interface Flyable { void fly(); }
class Bird implements Flyable { ... }
class Airplane implements Flyable { ... }

⚠️ 坑 1:接口的字段默认 public static final,不能改:

java
interface MyInterface {
    int MAX = 100;
}
// MyInterface.MAX = 200;   // ❌ final 不能改

⚠️ 坑 2:default 方法多实现时可能冲突:

java
interface A { default void hello() { System.out.println("A"); } }
interface B { default void hello() { System.out.println("B"); } }
class C implements A, B {
    // ❌ 编译报错:需要显式重写 hello()
    @Override
    public void hello() { A.super.hello(); }   // 显式选一个
}

四、实战:策略模式 ​

接口 + 组合,比继承更灵活:

java
interface DiscountStrategy {
    double apply(double price);
}

class VipDiscount implements DiscountStrategy {
    public double apply(double price) { return price * 0.8; }
}

class HolidayDiscount implements DiscountStrategy {
    public double apply(double price) { return price * 0.7; }
}

class Order {
    private DiscountStrategy strategy;

    public void setStrategy(DiscountStrategy strategy) {  // 运行时切换策略
        this.strategy = strategy;
    }

    public double checkout(double price) {
        return strategy.apply(price);
    }
}

// 使用
Order order = new Order();
order.setStrategy(new VipDiscount());
System.out.println(order.checkout(100));   // 80
order.setStrategy(new HolidayDiscount());
System.out.println(order.checkout(100));   // 70

五、本章小结 ​

要点关键
抽象类不能实例化,可包含抽象方法和普通方法
接口行为的抽象,Java 8+ 支持 default / static 方法
多实现一个类可实现多个接口(逗号分隔)
选择共性用抽象类(is-a),能力用接口(has-a)
default 冲突多接口 default 同名需显式重写

动手练习 ​

  1. Shape 抽象类:Shape → Circle / Rectangle,各自实现 area() 和 perimeter()
  2. Flyable 接口:Bird / Airplane / Superman 实现 fly(),写一个 makeThemFly(Flyable[]) 方法
  3. 策略模式:写一个 PaymentStrategy 接口(Alipay / WeChatPay),Order 类持有策略引用

下一章:第 9 章:枚举与内部类 →

本站基于 VitePress 构建 · 由 StackHub 团队维护