Java 接口与抽象类

接口和抽象类是 Java 实现多态和代码抽象的重要机制。

抽象类(Abstract Class)

什么是抽象类

抽象类是不能被实例化的类,用于定义子类必须实现的抽象方法。

// 抽象类:使用 abstract 关键字
public abstract class Animal {
    protected String name;
    
    public Animal(String name) {
        this.name = name;
    }
    
    // 抽象方法:只有声明,没有实现
    // 子类必须实现抽象方法
    public abstract void makeSound();
    
    // 普通方法:可以有实现
    public void eat() {
        System.out.println(name + " 正在吃东西");
    }
    
    // 抽象类可以有构造方法
    // 抽象类可以有成员变量
    // 抽象类可以有普通方法
}
 
// 子类必须实现抽象方法
public class Dog extends Animal {
    public Dog(String name) {
        super(name);
    }
    
    @Override
    public void makeSound() {
        System.out.println(name + " 汪汪叫");
    }
}
 
// 如果子类不实现所有抽象方法,子类也必须是抽象的
public abstract class Mammal extends Animal {
    public Mammal(String name) {
        super(name);
    }
    
    // 没有实现 makeSound(),所以 Mammal 也是抽象类
}

抽象类的特点

public abstract class AbstractExample {
    // 1. 可以包含抽象方法
    public abstract void abstractMethod();
    
    // 2. 可以包含普通方法
    public void normalMethod() {
        System.out.println("普通方法");
    }
    
    // 3. 可以包含成员变量
    protected int value = 10;
    
    // 4. 可以包含构造方法
    public AbstractExample() {
        System.out.println("抽象类构造方法");
    }
    
    // 5. 不能实例化
    // AbstractExample obj = new AbstractExample();  // 错误
    
    // 6. 可以有静态方法
    public static void staticMethod() {
        System.out.println("静态方法");
    }
}

接口(Interface)

什么是接口

接口是一组抽象方法的集合,定义了一个类应该实现的方法。

// 接口定义:使用 interface 关键字
public interface Flyable {
    // 接口中的方法默认是 public abstract
    void fly();  // 等价于 public abstract void fly();
    
    // Java 8+ 可以在接口中定义默认方法
    default void land() {
        System.out.println("着陆");
    }
    
    // Java 8+ 可以在接口中定义静态方法
    static void showInfo() {
        System.out.println("这是一个可飞行的接口");
    }
}
 
// 类实现接口:使用 implements 关键字
public class Bird implements Flyable {
    @Override
    public void fly() {
        System.out.println("鸟在飞");
    }
}
 
// 一个类可以实现多个接口
public interface Swimmable {
    void swim();
}
 
public class Duck implements Flyable, Swimmable {
    @Override
    public void fly() {
        System.out.println("鸭子飞");
    }
    
    @Override
    public void swim() {
        System.out.println("鸭子游");
    }
}

接口的特点

public interface InterfaceExample {
    // 1. 接口中的方法默认是 public abstract
    void method1();
    
    // 2. 接口中的变量默认是 public static final(常量)
    int MAX_SIZE = 100;  // 等价于 public static final int MAX_SIZE = 100;
    
    // 3. Java 8+ 支持默认方法
    default void defaultMethod() {
        System.out.println("默认方法");
    }
    
    // 4. Java 8+ 支持静态方法
    static void staticMethod() {
        System.out.println("静态方法");
    }
    
    // 5. Java 9+ 支持私有方法
    private void privateMethod() {
        System.out.println("私有方法");
    }
}

接口的继承

// 接口可以继承其他接口
public interface Animal {
    void eat();
}
 
public interface Flyable {
    void fly();
}
 
// 接口可以多继承
public interface Bird extends Animal, Flyable {
    void sing();
}
 
// 实现接口的类必须实现所有方法
public class Sparrow implements Bird {
    @Override
    public void eat() {
        System.out.println("麻雀吃");
    }
    
    @Override
    public void fly() {
        System.out.println("麻雀飞");
    }
    
    @Override
    public void sing() {
        System.out.println("麻雀唱");
    }
}

抽象类 vs 接口

对比表

特性抽象类接口
关键字abstract classinterface
实例化不能不能
方法可以有抽象方法和普通方法只能有抽象方法(Java 8+ 可以有默认方法)
变量可以有各种变量只能是常量(public static final)
构造方法可以有不能有
继承单继承多实现
访问修饰符可以是任意默认 public

使用场景

// 抽象类:用于有共同实现的类层次结构
public abstract class Vehicle {
    protected String brand;
    
    public Vehicle(String brand) {
        this.brand = brand;
    }
    
    // 所有车辆都有启动方法
    public void start() {
        System.out.println(brand + " 启动");
    }
    
    // 不同车辆有不同的行驶方式
    public abstract void drive();
}
 
// 接口:用于定义行为契约
public interface Drawable {
    void draw();
}
 
public interface Clickable {
    void onClick();
}
 
// 一个类可以实现多个接口
public class Button implements Drawable, Clickable {
    @Override
    public void draw() {
        System.out.println("绘制按钮");
    }
    
    @Override
    public void onClick() {
        System.out.println("按钮被点击");
    }
}

实际应用示例

示例1:支付系统

// 支付接口
public interface Payment {
    void pay(double amount);
    void refund(double amount);
}
 
// 支付宝支付
public class AlipayPayment implements Payment {
    @Override
    public void pay(double amount) {
        System.out.println("使用支付宝支付:" + amount + " 元");
    }
    
    @Override
    public void refund(double amount) {
        System.out.println("支付宝退款:" + amount + " 元");
    }
}
 
// 微信支付
public class WeChatPayment implements Payment {
    @Override
    public void pay(double amount) {
        System.out.println("使用微信支付:" + amount + " 元");
    }
    
    @Override
    public void refund(double amount) {
        System.out.println("微信退款:" + amount + " 元");
    }
}
 
// 使用接口实现多态
public class PaymentService {
    private Payment payment;
    
    public PaymentService(Payment payment) {
        this.payment = payment;
    }
    
    public void processPayment(double amount) {
        payment.pay(amount);
    }
}

示例2:图形绘制系统

// 可绘制接口
public interface Drawable {
    void draw();
    double getArea();
}
 
// 抽象图形类
public abstract class Shape implements Drawable {
    protected String color;
    
    public Shape(String color) {
        this.color = color;
    }
    
    public String getColor() {
        return color;
    }
}
 
// 圆形
public class Circle extends Shape {
    private double radius;
    
    public Circle(String color, double radius) {
        super(color);
        this.radius = radius;
    }
    
    @Override
    public void draw() {
        System.out.println("绘制圆形,颜色:" + color + ",半径:" + radius);
    }
    
    @Override
    public double getArea() {
        return Math.PI * radius * radius;
    }
}
 
// 矩形
public class Rectangle extends Shape {
    private double width;
    private double height;
    
    public Rectangle(String color, double width, double height) {
        super(color);
        this.width = width;
        this.height = height;
    }
    
    @Override
    public void draw() {
        System.out.println("绘制矩形,颜色:" + color + ",宽:" + width + ",高:" + height);
    }
    
    @Override
    public double getArea() {
        return width * height;
    }
}

总结

接口和抽象类都是实现抽象和多态的重要机制:

  • 抽象类:用于有共同实现的类层次结构,单继承
  • 接口:用于定义行为契约,多实现
  • 选择原则
    • 需要定义模板方法时使用抽象类
    • 需要定义行为契约时使用接口
    • 需要多继承时使用接口

掌握接口和抽象类可以编写更加灵活和可扩展的代码。


相关链接


java 面向对象 接口 抽象类