← 返回首页
🔌

Java接口详解:定义、实现与默认方法

📂 java ⏱ 4 min 700 words

Java接口详解:定义、实现与默认方法

概述

接口(Interface)是Java中定义抽象行为的机制。接口定义了一组方法规范,类可以实现接口来提供具体实现。接口支持多继承,一个类可以实现多个接口。

1. 接口的定义

基本接口

// 定义接口
public interface Drawable {
    // 抽象方法(默认public abstract)
    void draw();
    
    // 常量(默认public static final)
    int MAX_WIDTH = 100;
    int MAX_HEIGHT = 100;
    
    // 默认方法(Java 8+)
    default void fill() {
        System.out.println("填充默认颜色");
    }
    
    // 静态方法(Java 8+)
    static void printInfo() {
        System.out.println("这是一个可绘制的接口");
    }
    
    // 私有方法(Java 9+)
    private void validate() {
        System.out.println("验证绘图参数");
    }
}

// 实现接口
public class Circle implements Drawable {
    private double radius;
    
    public Circle(double radius) {
        this.radius = radius;
    }
    
    @Override
    public void draw() {
        System.out.println("绘制圆形,半径: " + radius);
    }
}

// 测试
public class InterfaceTest {
    public static void main(String[] args) {
        Circle circle = new Circle(5);
        circle.draw();      // 调用实现的方法
        circle.fill();      // 调用默认方法
        Drawable.printInfo();  // 调用静态方法
        
        System.out.println("最大宽度: " + Drawable.MAX_WIDTH);  // 访问常量
    }
}

2. 多接口实现

一个类实现多个接口

public interface Swimmable {
    void swim();
    
    default void floatOnWater() {
        System.out.println("漂浮在水面上");
    }
}

public interface Flyable {
    void fly();
    
    default void glide() {
        System.out.println("滑翔飞行");
    }
}

public interface Walkable {
    void walk();
}

// 实现多个接口
public class Duck implements Swimmable, Flyable, Walkable {
    @Override
    public void swim() {
        System.out.println("鸭子游泳");
    }
    
    @Override
    public void fly() {
        System.out.println("鸭子飞行");
    }
    
    @Override
    public void walk() {
        System.out.println("鸭子走路");
    }
}

// 测试
public class MultiInterfaceTest {
    public static void main(String[] args) {
        Duck duck = new Duck();
        
        duck.swim();
        duck.fly();
        duck.walk();
        duck.floatOnWater();
        duck.glide();
        
        // 接口类型引用
        Swimmable swimmable = duck;
        swimmable.swim();
        
        Flyable flyable = duck;
        flyable.fly();
    }
}

3. 接口继承

// 父接口
public interface Shape {
    double area();
    double perimeter();
    
    default void display() {
        System.out.println("面积: " + area());
        System.out.println("周长: " + perimeter());
    }
}

// 子接口继承父接口
public interface Resizable extends Shape {
    void resize(double factor);
    
    @Override
    default void display() {
        Shape.super.display();  // 调用父接口的默认方法
        System.out.println("调整大小");
    }
}

// 实现子接口
public class Circle implements Resizable {
    private double radius;
    
    public Circle(double radius) {
        this.radius = radius;
    }
    
    @Override
    public double area() {
        return Math.PI * radius * radius;
    }
    
    @Override
    public double perimeter() {
        return 2 * Math.PI * radius;
    }
    
    @Override
    public void resize(double factor) {
        this.radius *= factor;
        System.out.println("调整后半径: " + radius);
    }
}

// 测试
public class InterfaceInheritanceTest {
    public static void main(String[] args) {
        Circle circle = new Circle(5);
        circle.display();
        circle.resize(2);
        circle.display();
    }
}

4. 函数式接口

单抽象方法接口

@FunctionalInterface  // 注解表示函数式接口
public interface Calculator {
    int calculate(int a, int b);
    
    // 可以有默认方法
    default int add(int a, int b) {
        return a + b;
    }
    
    // 可以有静态方法
    static int multiply(int a, int b) {
        return a * b;
    }
}

// 使用Lambda表达式实现函数式接口
public class FunctionalInterfaceTest {
    public static void main(String[] args) {
        // 使用Lambda表达式
        Calculator add = (a, b) -> a + b;
        Calculator subtract = (a, b) -> a - b;
        Calculator multiply = (a, b) -> a * b;
        
        System.out.println("加法: " + add.calculate(10, 5));
        System.out.println("减法: " + subtract.calculate(10, 5));
        System.out.println("乘法: " + multiply.calculate(10, 5));
        
        // 使用方法引用
        Calculator add2 = Integer::sum;
        System.out.println("加法2: " + add2.calculate(10, 5));
    }
}

5. 接口与抽象类的区别

// 抽象类
public abstract class AbstractAnimal {
    protected String name;
    
    public AbstractAnimal(String name) {
        this.name = name;
    }
    
    public abstract void sound();
    
    public void eat() {
        System.out.println(name + "吃东西");
    }
}

// 接口
public interface AnimalInterface {
    void sound();
    
    default void eat() {
        System.out.println("吃东西");
    }
}

// 类可以继承一个抽象类,但可以实现多个接口
public class Dog extends AbstractAnimal implements AnimalInterface {
    public Dog(String name) {
        super(name);
    }
    
    @Override
    public void sound() {
        System.out.println("汪汪汪");
    }
    
    @Override
    public void eat() {
        System.out.println(name + "吃骨头");
    }
}

6. 实际应用示例

插件系统

public interface Plugin {
    String getName();
    String getVersion();
    void execute();
    
    default void log(String message) {
        System.out.println("[" + getName() + "] " + message);
    }
}

public class LoggerPlugin implements Plugin {
    @Override
    public String getName() {
        return "Logger";
    }
    
    @Override
    public String getVersion() {
        return "1.0.0";
    }
    
    @Override
    public void execute() {
        log("执行日志记录");
    }
}

public class DatabasePlugin implements Plugin {
    @Override
    public String getName() {
        return "Database";
    }
    
    @Override
    public String getVersion() {
        return "2.0.0";
    }
    
    @Override
    public void execute() {
        log("执行数据库操作");
    }
}

public class PluginManager {
    private List<Plugin> plugins = new ArrayList<>();
    
    public void registerPlugin(Plugin plugin) {
        plugins.add(plugin);
        plugin.log("插件已注册");
    }
    
    public void executeAllPlugins() {
        for (Plugin plugin : plugins) {
            plugin.execute();
        }
    }
}

public class PluginTest {
    public static void main(String[] args) {
        PluginManager manager = new PluginManager();
        
        manager.registerPlugin(new LoggerPlugin());
        manager.registerPlugin(new DatabasePlugin());
        
        System.out.println("---");
        manager.executeAllPlugins();
    }
}

7. 最佳实践

  1. 使用接口定义行为:接口用于定义类应该具有的行为
  2. 使用抽象类共享代码:当多个类有共同代码时,使用抽象类
  3. 优先使用接口:需要多继承时使用接口
  4. 保持接口小而专注:每个接口应该只定义一组相关的功能
  5. 使用@FunctionalInterface:单抽象方法接口使用此注解

总结

接口是Java中定义抽象行为的重要机制。通过接口,可以实现多继承、定义契约、支持Lambda表达式等。理解接口的使用规则和最佳实践,对于设计灵活、可扩展的Java程序至关重要。