Java 接口(Interface)指南

91 阅读12分钟

🎯 Java 接口(Interface)完全指南

📖 接口基本概念

什么是接口?

接口是完全抽象的类型,定义了一组方法契约,让不相关的类能够实现相同的行为。

核心特征

  • 使用 interface 关键字
  • 不能有实例变量(只能有常量)
  • 方法默认是 public abstract(Java 8前)
  • 支持多重实现(一个类可实现多个接口)
  • 用于定义能力契约

🎯 接口的基本语法

1. 最简单的接口

// 定义接口
interface Animal {
    // 抽象方法(默认public abstract)
    void makeSound();
    
    // 常量(默认public static final)
    String TYPE = "动物";
}

// 实现接口
class Dog implements Animal {
    // 必须实现接口的所有方法
    @Override
    public void makeSound() {
        System.out.println("狗汪汪叫");
    }
}

class Cat implements Animal {
    @Override
    public void makeSound() {
        System.out.println("猫喵喵叫");
    }
}

public class InterfaceBasic {
    public static void main(String[] args) {
        // 多态:接口引用指向实现类对象
        Animal dog = new Dog();
        Animal cat = new Cat();
        
        dog.makeSound();  // 输出:狗汪汪叫
        cat.makeSound();  // 输出:猫喵喵叫
        
        // 访问接口常量
        System.out.println("类型: " + Animal.TYPE);
        
        // 接口不能实例化
        // Animal animal = new Animal();  // 编译错误
    }
}

2. 接口 vs 抽象类

// 接口定义行为
interface Flyable {
    void fly();
}

interface Swimmable {
    void swim();
}

// 抽象类提供部分实现
abstract class Bird {
    protected String name;
    
    public Bird(String name) {
        this.name = name;
    }
    
    public abstract void makeSound();
    
    public void eat() {
        System.out.println(name + "在吃东西");
    }
}

// 类可以继承一个类,实现多个接口
class Duck extends Bird implements Flyable, Swimmable {
    public Duck(String name) {
        super(name);
    }
    
    @Override
    public void makeSound() {
        System.out.println(name + "嘎嘎叫");
    }
    
    @Override
    public void fly() {
        System.out.println(name + "在低空飞行");
    }
    
    @Override
    public void swim() {
        System.out.println(name + "在水面游泳");
    }
}

class Penguin extends Bird implements Swimmable {
    public Penguin(String name) {
        super(name);
    }
    
    @Override
    public void makeSound() {
        System.out.println(name + "嘎嘎叫(企鹅)");
    }
    
    @Override
    public void swim() {
        System.out.println(name + "在水中游泳");
    }
    
    // 企鹅不会飞,所以不实现Flyable
}

public class InterfaceVsAbstract {
    public static void main(String[] args) {
        System.out.println("=== 接口 vs 抽象类 ===");
        
        Duck duck = new Duck("唐老鸭");
        Penguin penguin = new Penguin("企鹅");
        
        duck.eat();
        duck.makeSound();
        duck.fly();
        duck.swim();
        
        System.out.println();
        
        penguin.eat();
        penguin.makeSound();
        penguin.swim();
        
        // 多态演示
        System.out.println("\n=== 多态演示 ===");
        
        // 接口引用
        Flyable flyer = duck;
        Swimmable swimmer1 = duck;
        Swimmable swimmer2 = penguin;
        
        flyer.fly();
        swimmer1.swim();
        swimmer2.swim();
        
        // 检查对象是否实现某接口
        System.out.println("\n鸭子会飞吗?" + (duck instanceof Flyable));
        System.out.println("企鹅会飞吗?" + (penguin instanceof Flyable));
    }
}

🔧 接口的现代特性(Java 8+)

1. 默认方法(Default Methods)

interface Vehicle {
    // 抽象方法
    void start();
    void stop();
    
    // 默认方法(Java 8+)
    default void honk() {
        System.out.println("车辆鸣笛:嘟嘟!");
    }
    
    // 静态方法(Java 8+)
    static void showInfo() {
        System.out.println("这是一个交通工具接口");
    }
}

interface Radio {
    default void playMusic() {
        System.out.println("播放音乐");
    }
}

class Car implements Vehicle, Radio {
    private String brand;
    
    public Car(String brand) {
        this.brand = brand;
    }
    
    @Override
    public void start() {
        System.out.println(brand + "汽车启动");
    }
    
    @Override
    public void stop() {
        System.out.println(brand + "汽车停止");
    }
    
    // 可以选择重写默认方法
    @Override
    public void honk() {
        System.out.println(brand + "汽车鸣笛:叭叭!");
    }
}

class Bicycle implements Vehicle {
    @Override
    public void start() {
        System.out.println("自行车出发");
    }
    
    @Override
    public void stop() {
        System.out.println("自行车停车");
    }
    
    // 使用接口的默认honk方法
}

public class DefaultMethodDemo {
    public static void main(String[] args) {
        System.out.println("=== 默认方法演示 ===");
        
        Car car = new Car("丰田");
        car.start();
        car.stop();
        car.honk();      // 调用重写的默认方法
        car.playMusic(); // 来自Radio接口
        
        System.out.println();
        
        Bicycle bike = new Bicycle();
        bike.start();
        bike.stop();
        bike.honk();     // 调用Vehicle接口的默认方法
        
        // 调用接口静态方法
        Vehicle.showInfo();
        
        System.out.println("\n默认方法的用途:");
        System.out.println("1. 向后兼容:向现有接口添加新方法");
        System.out.println("2. 提供通用实现");
        System.out.println("3. 减少重复代码");
    }
}

2. 静态方法(Static Methods)

// 工具接口
interface MathUtils {
    // 静态方法(Java 8+)
    static double add(double a, double b) {
        return a + b;
    }
    
    static double multiply(double a, double b) {
        return a * b;
    }
    
    static boolean isEven(int number) {
        return number % 2 == 0;
    }
    
    // 常量
    double PI = 3.141592653589793;
}

// 验证工具
interface Validator {
    static boolean isValidEmail(String email) {
        return email != null && email.contains("@") && email.contains(".");
    }
    
    static boolean isValidPhone(String phone) {
        return phone != null && phone.matches("\\d{11}");
    }
    
    static boolean isStrongPassword(String password) {
        return password != null && password.length() >= 8 &&
               password.matches(".*[A-Z].*") &&
               password.matches(".*[a-z].*") &&
               password.matches(".*\\d.*");
    }
}

public class StaticMethodDemo {
    public static void main(String[] args) {
        System.out.println("=== 接口静态方法 ===");
        
        // 直接通过接口名调用静态方法
        System.out.println("5 + 3 = " + MathUtils.add(5, 3));
        System.out.println("5 × 3 = " + MathUtils.multiply(5, 3));
        System.out.println("4是偶数?" + MathUtils.isEven(4));
        
        System.out.println("\n=== 数据验证 ===");
        String email = "test@example.com";
        String phone = "13800138000";
        String password = "Pass1234";
        
        System.out.println("邮箱验证: " + Validator.isValidEmail(email));
        System.out.println("手机验证: " + Validator.isValidPhone(phone));
        System.out.println("密码强度: " + Validator.isStrongPassword(password));
        
        System.out.println("\n静态方法的用途:");
        System.out.println("1. 工具方法:不需要对象实例");
        System.out.println("2. 工厂方法:创建对象");
        System.out.println("3. 辅助方法:与接口相关的操作");
    }
}

3. 私有方法(Java 9+)

// Java 9+ 支持私有方法
interface Calculator {
    // 默认方法
    default double calculateArea(double radius) {
        validateRadius(radius);
        return PI * radius * radius;
    }
    
    default double calculateCircumference(double radius) {
        validateRadius(radius);
        return 2 * PI * radius;
    }
    
    // 私有方法(Java 9+)
    private void validateRadius(double radius) {
        if (radius <= 0) {
            throw new IllegalArgumentException("半径必须大于0");
        }
    }
    
    // 私有静态方法(Java 9+)
    private static void log(String message) {
        System.out.println("[LOG] " + message);
    }
    
    // 静态方法调用私有静态方法
    static void calculateAndLog(double radius) {
        log("计算半径: " + radius);
        double area = Math.PI * radius * radius;
        log("面积: " + area);
    }
    
    // 常量
    double PI = Math.PI;
}

class CircleCalculator implements Calculator {
    // 使用接口的默认方法
}

public class PrivateMethodDemo {
    public static void main(String[] args) {
        System.out.println("=== 私有方法演示(Java 9+) ===");
        
        CircleCalculator calc = new CircleCalculator();
        
        try {
            System.out.println("半径为5的圆面积: " + calc.calculateArea(5));
            System.out.println("半径为5的圆周长: " + calc.calculateCircumference(5));
            
            // 测试验证
            System.out.println("半径为0的圆面积: " + calc.calculateArea(0));
        } catch (IllegalArgumentException e) {
            System.out.println("错误: " + e.getMessage());
        }
        
        // 调用静态方法
        Calculator.calculateAndLog(10);
        
        System.out.println("\n私有方法的用途:");
        System.out.println("1. 提取重复代码");
        System.out.println("2. 隐藏实现细节");
        System.out.println("3. 提高代码复用性");
    }
}

🏗️ 接口的设计模式应用

1. 策略模式(Strategy Pattern)

// 策略接口
interface PaymentStrategy {
    void pay(double amount);
    String getPaymentMethod();
}

// 具体策略
class CreditCardPayment implements PaymentStrategy {
    private String cardNumber;
    
    public CreditCardPayment(String cardNumber) {
        this.cardNumber = cardNumber;
    }
    
    @Override
    public void pay(double amount) {
        System.out.printf("使用信用卡支付 $%.2f,卡号: %s%n", 
                         amount, maskCardNumber());
    }
    
    @Override
    public String getPaymentMethod() {
        return "信用卡";
    }
    
    private String maskCardNumber() {
        if (cardNumber.length() > 4) {
            return "****-****-****-" + cardNumber.substring(cardNumber.length() - 4);
        }
        return cardNumber;
    }
}

class AlipayPayment implements PaymentStrategy {
    private String account;
    
    public AlipayPayment(String account) {
        this.account = account;
    }
    
    @Override
    public void pay(double amount) {
        System.out.printf("使用支付宝支付 $%.2f,账户: %s%n", amount, account);
    }
    
    @Override
    public String getPaymentMethod() {
        return "支付宝";
    }
}

class WechatPayment implements PaymentStrategy {
    @Override
    public void pay(double amount) {
        System.out.printf("使用微信支付 $%.2f%n", amount);
    }
    
    @Override
    public String getPaymentMethod() {
        return "微信支付";
    }
}

// 上下文类
class ShoppingCart {
    private PaymentStrategy paymentStrategy;
    
    public void setPaymentStrategy(PaymentStrategy paymentStrategy) {
        this.paymentStrategy = paymentStrategy;
    }
    
    public void checkout(double amount) {
        if (paymentStrategy == null) {
            System.out.println("请先选择支付方式");
            return;
        }
        
        System.out.println("\n=== 结账 ===");
        System.out.println("支付方式: " + paymentStrategy.getPaymentMethod());
        System.out.println("金额: $" + amount);
        paymentStrategy.pay(amount);
        System.out.println("支付完成,感谢购买!");
    }
}

public class StrategyPatternDemo {
    public static void main(String[] args) {
        System.out.println("=== 策略模式演示 ===");
        
        ShoppingCart cart = new ShoppingCart();
        
        // 动态切换支付策略
        System.out.println("\n1. 使用信用卡支付:");
        cart.setPaymentStrategy(new CreditCardPayment("1234567812345678"));
        cart.checkout(100.50);
        
        System.out.println("\n2. 使用支付宝支付:");
        cart.setPaymentStrategy(new AlipayPayment("user@alipay.com"));
        cart.checkout(200.00);
        
        System.out.println("\n3. 使用微信支付:");
        cart.setPaymentStrategy(new WechatPayment());
        cart.checkout(50.25);
        
        System.out.println("\n策略模式优点:");
        System.out.println("1. 开闭原则:新增策略不影响现有代码");
        System.out.println("2. 消除条件语句:避免大量的if-else");
        System.out.println("3. 提高复用性:策略可以独立使用");
    }
}

2. 工厂模式(Factory Pattern)

// 产品接口
interface Shape {
    void draw();
    double getArea();
}

// 具体产品
class Circle implements Shape {
    private double radius;
    
    public Circle(double radius) {
        this.radius = radius;
    }
    
    @Override
    public void draw() {
        System.out.println("绘制圆形,半径: " + radius);
    }
    
    @Override
    public double getArea() {
        return Math.PI * radius * radius;
    }
}

class Rectangle implements Shape {
    private double width;
    private double height;
    
    public Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }
    
    @Override
    public void draw() {
        System.out.printf("绘制矩形,宽: %.1f,高: %.1f%n", width, height);
    }
    
    @Override
    public double getArea() {
        return width * height;
    }
}

class Triangle implements Shape {
    private double base;
    private double height;
    
    public Triangle(double base, double height) {
        this.base = base;
        this.height = height;
    }
    
    @Override
    public void draw() {
        System.out.printf("绘制三角形,底: %.1f,高: %.1f%n", base, height);
    }
    
    @Override
    public double getArea() {
        return 0.5 * base * height;
    }
}

// 工厂接口
interface ShapeFactory {
    Shape createShape(double... params);
}

// 具体工厂
class CircleFactory implements ShapeFactory {
    @Override
    public Shape createShape(double... params) {
        if (params.length < 1) {
            throw new IllegalArgumentException("需要半径参数");
        }
        return new Circle(params[0]);
    }
}

class RectangleFactory implements ShapeFactory {
    @Override
    public Shape createShape(double... params) {
        if (params.length < 2) {
            throw new IllegalArgumentException("需要宽和高参数");
        }
        return new Rectangle(params[0], params[1]);
    }
}

class TriangleFactory implements ShapeFactory {
    @Override
    public Shape createShape(double... params) {
        if (params.length < 2) {
            throw new IllegalArgumentException("需要底和高参数");
        }
        return new Triangle(params[0], params[1]);
    }
}

// 工厂创建器
class ShapeFactoryCreator {
    public static ShapeFactory getFactory(String shapeType) {
        switch (shapeType.toLowerCase()) {
            case "circle":
                return new CircleFactory();
            case "rectangle":
                return new RectangleFactory();
            case "triangle":
                return new TriangleFactory();
            default:
                throw new IllegalArgumentException("不支持的形状: " + shapeType);
        }
    }
}

public class FactoryPatternDemo {
    public static void main(String[] args) {
        System.out.println("=== 工厂模式演示 ===");
        
        // 创建圆形
        ShapeFactory circleFactory = ShapeFactoryCreator.getFactory("circle");
        Shape circle = circleFactory.createShape(5.0);
        circle.draw();
        System.out.println("面积: " + circle.getArea());
        
        // 创建矩形
        ShapeFactory rectFactory = ShapeFactoryCreator.getFactory("rectangle");
        Shape rectangle = rectFactory.createShape(4.0, 6.0);
        rectangle.draw();
        System.out.println("面积: " + rectangle.getArea());
        
        // 创建三角形
        ShapeFactory triFactory = ShapeFactoryCreator.getFactory("triangle");
        Shape triangle = triFactory.createShape(3.0, 4.0);
        triangle.draw();
        System.out.println("面积: " + triangle.getArea());
    }
}

🔧 接口的实际应用

1. 回调机制(Callback)

// 回调接口
interface DownloadCallback {
    void onProgress(int percent);
    void onComplete(String filePath);
    void onError(String errorMessage);
}

// 下载器
class FileDownloader {
    public void download(String url, DownloadCallback callback) {
        System.out.println("开始下载: " + url);
        
        // 模拟下载过程
        for (int i = 0; i <= 100; i += 10) {
            try {
                Thread.sleep(200);  // 模拟下载时间
            } catch (InterruptedException e) {
                callback.onError("下载被中断");
                return;
            }
            
            callback.onProgress(i);
        }
        
        String filePath = "/downloads/" + url.substring(url.lastIndexOf("/") + 1);
        callback.onComplete(filePath);
    }
}

// 使用匿名内部类实现回调
public class CallbackDemo {
    public static void main(String[] args) {
        System.out.println("=== 回调机制演示 ===");
        
        FileDownloader downloader = new FileDownloader();
        
        // 使用匿名内部类实现回调接口
        downloader.download("http://example.com/file.zip", 
            new DownloadCallback() {
                @Override
                public void onProgress(int percent) {
                    System.out.println("下载进度: " + percent + "%");
                }
                
                @Override
                public void onComplete(String filePath) {
                    System.out.println("下载完成,文件保存到: " + filePath);
                }
                
                @Override
                public void onError(String errorMessage) {
                    System.out.println("下载错误: " + errorMessage);
                }
            });
        
        // 使用Lambda表达式(Java 8+)
        System.out.println("\n=== 使用Lambda表达式 ===");
        
        downloader.download("http://example.com/image.jpg",
            new DownloadCallback() {
                @Override
                public void onProgress(int percent) {
                    if (percent % 20 == 0) {
                        System.out.println("进度: " + percent + "%");
                    }
                }
                
                @Override
                public void onComplete(String filePath) {
                    System.out.println("✅ 下载成功: " + filePath);
                }
                
                @Override
                public void onError(String errorMessage) {
                    System.out.println("❌ 下载失败: " + errorMessage);
                }
            });
    }
}

2. 插件系统设计

// 插件接口
interface Plugin {
    String getName();
    String getVersion();
    void initialize();
    void execute();
    void cleanup();
}

// 插件管理器
class PluginManager {
    private List<Plugin> plugins = new ArrayList<>();
    
    public void registerPlugin(Plugin plugin) {
        plugins.add(plugin);
        System.out.println("注册插件: " + plugin.getName());
    }
    
    public void initializeAll() {
        System.out.println("\n=== 初始化所有插件 ===");
        for (Plugin plugin : plugins) {
            plugin.initialize();
        }
    }
    
    public void executeAll() {
        System.out.println("\n=== 执行所有插件 ===");
        for (Plugin plugin : plugins) {
            System.out.println("\n执行插件: " + plugin.getName());
            plugin.execute();
        }
    }
    
    public void cleanupAll() {
        System.out.println("\n=== 清理所有插件 ===");
        for (Plugin plugin : plugins) {
            plugin.cleanup();
        }
    }
}

// 具体插件
class LoggerPlugin implements Plugin {
    @Override
    public String getName() {
        return "日志插件";
    }
    
    @Override
    public String getVersion() {
        return "1.0.0";
    }
    
    @Override
    public void initialize() {
        System.out.println("初始化日志系统...");
    }
    
    @Override
    public void execute() {
        System.out.println("记录应用程序日志");
    }
    
    @Override
    public void cleanup() {
        System.out.println("关闭日志文件");
    }
}

class SecurityPlugin implements Plugin {
    @Override
    public String getName() {
        return "安全插件";
    }
    
    @Override
    public String getVersion() {
        return "2.1.0";
    }
    
    @Override
    public void initialize() {
        System.out.println("初始化安全模块...");
    }
    
    @Override
    public void execute() {
        System.out.println("检查系统安全状态");
        System.out.println("扫描病毒和恶意软件");
    }
    
    @Override
    public void cleanup() {
        System.out.println("释放安全资源");
    }
}

class BackupPlugin implements Plugin {
    @Override
    public String getName() {
        return "备份插件";
    }
    
    @Override
    public String getVersion() {
        return "1.2.0";
    }
    
    @Override
    public void initialize() {
        System.out.println("初始化备份系统...");
    }
    
    @Override
    public void execute() {
        System.out.println("执行数据备份");
        System.out.println("压缩备份文件");
    }
    
    @Override
    public void cleanup() {
        System.out.println("清理临时备份文件");
    }
}

public class PluginSystem {
    public static void main(String[] args) {
        System.out.println("=== 插件系统演示 ===");
        
        PluginManager manager = new PluginManager();
        
        // 注册插件
        manager.registerPlugin(new LoggerPlugin());
        manager.registerPlugin(new SecurityPlugin());
        manager.registerPlugin(new BackupPlugin());
        
        // 运行插件系统
        manager.initializeAll();
        manager.executeAll();
        manager.cleanupAll();
        
        System.out.println("\n插件系统优点:");
        System.out.println("1. 可扩展性:动态添加新功能");
        System.out.println("2. 模块化:每个插件独立");
        System.out.println("3. 热插拔:运行时加载/卸载");
        System.out.println("4. 接口统一:标准化插件开发");
    }
}

3. 数据访问层设计

// 数据访问对象接口
interface UserDao {
    // CRUD 操作
    User findById(int id);
    List<User> findAll();
    void save(User user);
    void update(User user);
    void delete(int id);
    
    // 业务方法
    List<User> findByRole(String role);
    int count();
    
    // 默认方法
    default boolean exists(int id) {
        return findById(id) != null;
    }
    
    // 静态方法
    static void validateUser(User user) {
        if (user == null) {
            throw new IllegalArgumentException("用户不能为空");
        }
        if (user.getName() == null || user.getName().trim().isEmpty()) {
            throw new IllegalArgumentException("用户名不能为空");
        }
    }
}

// 实体类
class User {
    private int id;
    private String name;
    private String email;
    private String role;
    
    public User(int id, String name, String email, String role) {
        this.id = id;
        this.name = name;
        this.email = email;
        this.role = role;
    }
    
    // Getter 和 Setter
    public int getId() { return id; }
    public void setId(int id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public String getEmail() { return email; }
    public void setEmail(String email) { this.email = email; }
    public String getRole() { return role; }
    public void setRole(String role) { this.role = role; }
    
    @Override
    public String toString() {
        return String.format("User{id=%d, name='%s', email='%s', role='%s'}", 
                           id, name, email, role);
    }
}

// MySQL 实现
class MySqlUserDao implements UserDao {
    // 模拟数据库
    private Map<Integer, User> database = new HashMap<>();
    private int nextId = 1;
    
    public MySqlUserDao() {
        // 初始化测试数据
        save(new User(nextId++, "张三", "zhangsan@example.com", "admin"));
        save(new User(nextId++, "李四", "lisi@example.com", "user"));
        save(new User(nextId++, "王五", "wangwu@example.com", "user"));
    }
    
    @Override
    public User findById(int id) {
        return database.get(id);
    }
    
    @Override
    public List<User> findAll() {
        return new ArrayList<>(database.values());
    }
    
    @Override
    public void save(User user) {
        UserDao.validateUser(user);
        
        if (user.getId() == 0) {
            user.setId(nextId++);
        }
        database.put(user.getId(), user);
        System.out.println("保存用户: " + user.getName());
    }
    
    @Override
    public void update(User user) {
        UserDao.validateUser(user);
        
        if (database.containsKey(user.getId())) {
            database.put(user.getId(), user);
            System.out.println("更新用户: " + user.getName());
        } else {
            throw new IllegalArgumentException("用户不存在: " + user.getId());
        }
    }
    
    @Override
    public void delete(int id) {
        User user = database.remove(id);
        if (user != null) {
            System.out.println("删除用户: " + user.getName());
        }
    }
    
    @Override
    public List<User> findByRole(String role) {
        List<User> result = new ArrayList<>();
        for (User user : database.values()) {
            if (role.equals(user.getRole())) {
                result.add(user);
            }
        }
        return result;
    }
    
    @Override
    public int count() {
        return database.size();
    }
}

public class DaoPatternDemo {
    public static void main(String[] args) {
        System.out.println("=== 数据访问层设计 ===");
        
        UserDao userDao = new MySqlUserDao();
        
        // 查找所有用户
        System.out.println("\n所有用户:");
        for (User user : userDao.findAll()) {
            System.out.println("  " + user);
        }
        
        // 查找特定用户
        System.out.println("\n查找ID=1的用户:");
        User user1 = userDao.findById(1);
        System.out.println("  找到: " + user1);
        
        // 使用默认方法
        System.out.println("\n检查用户是否存在:");
        System.out.println("  ID=1存在?" + userDao.exists(1));
        System.out.println("  ID=999存在?" + userDao.exists(999));
        
        // 新增用户
        System.out.println("\n新增用户:");
        User newUser = new User(0, "赵六", "zhaoliu@example.com", "user");
        userDao.save(newUser);
        
        // 按角色查找
        System.out.println("\n查找所有普通用户:");
        for (User user : userDao.findByRole("user")) {
            System.out.println("  " + user);
        }
        
        // 统计
        System.out.println("\n用户总数: " + userDao.count());
    }
}

💡 接口的最佳实践

1. 接口设计原则

// 好的接口设计
interface GoodDesign {
    // 1. 单一职责:一个接口只做一件事
    void performSingleTask();
    
    // 2. 方法名明确表达意图
    String getUserNameById(int userId);
    
    // 3. 参数尽量少
    void save(User user);  // 而不是 save(int id, String name, String email...)
    
    // 4. 使用默认方法提供通用实现
    default boolean isEmpty(String str) {
        return str == null || str.trim().isEmpty();
    }
    
    // 5. 使用静态方法提供工具功能
    static boolean isValidEmail(String email) {
        return email != null && email.contains("@");
    }
}

// ❌ 不好的接口设计
interface BadDesign {
    // 1. 接口过于庞大(违反单一职责)
    void doEverything();
    
    // 2. 方法名不明确
    void process(int a, int b, String c);
    
    // 3. 暴露实现细节
    void setInternalState(Object state);
    
    // 4. 过多的默认方法(应该是具体类的工作)
    default void complexImplementation() {
        // 太多实现代码
    }
}

public class DesignPrinciples {
    public static void main(String[] args) {
        System.out.println("接口设计原则:");
        System.out.println("\n✅ 应该:");
        System.out.println("1. 单一职责:一个接口一个目的");
        System.out.println("2. 接口隔离:不要强迫客户端依赖它们不用的方法");
        System.out.println("3. 命名清晰:方法名明确表达意图");
        System.out.println("4. 参数简洁:尽量少的参数");
        System.out.println("5. 使用默认方法:提供通用实现");
        
        System.out.println("\n❌ 不应该:");
        System.out.println("1. 创建过于庞大的接口");
        System.out.println("2. 暴露实现细节");
        System.out.println("3. 强迫客户端实现不需要的方法");
        System.out.println("4. 在接口中写太多具体代码");
    }
}

2. 接口 vs 抽象类选择指南

// 场景1:定义类型契约,不关心实现 → 使用接口
interface Drawable {
    void draw();
}

// 多个不相关的类都可以实现
class Circle implements Drawable { }
class Button implements Drawable { }
class Chart implements Drawable { }

// 场景2:共享代码,提供部分实现 → 使用抽象类
abstract class DataProcessor {
    // 共享的代码
    protected void validateInput(Object input) {
        // 通用验证逻辑
    }
    
    // 子类必须实现
    protected abstract void process(Object input);
    
    // 模板方法
    public final void execute(Object input) {
        validateInput(input);
        process(input);
        saveResult();
    }
    
    protected void saveResult() {
        // 默认实现
    }
}

// 场景3:需要多重继承 → 必须使用接口
interface Flyable {
    void fly();
}

interface Swimmable {
    void swim();
}

class Duck implements Flyable, Swimmable {
    // 实现多个接口
}

public class ChooseGuide {
    public static void main(String[] args) {
        System.out.println("接口 vs 抽象类选择指南:");
        System.out.println("\n使用接口当:");
        System.out.println("1. 需要定义类型契约");
        System.out.println("2. 需要多重继承");
        System.out.println("3. 不相关的类需要相同的行为");
        System.out.println("4. 想要指定数据类型(如List<T>)");
        
        System.out.println("\n使用抽象类当:");
        System.out.println("1. 需要在紧密相关的类间共享代码");
        System.out.println("2. 需要控制子类的部分行为");
        System.out.println("3. 需要提供模板方法");
        System.out.println("4. 需要非public的方法和字段");
        
        System.out.println("\n现代Java实践中:");
        System.out.println("1. 优先使用接口(更加灵活)");
        System.out.println("2. 需要共享代码时使用抽象类");
        System.out.println("3. 接口 + 默认方法 ≈ 抽象类");
    }
}

📊 接口特性总结

特性Java 8 前Java 8Java 9+
抽象方法✅ 支持✅ 支持✅ 支持
常量✅ 支持✅ 支持✅ 支持
默认方法❌ 不支持✅ 支持✅ 支持
静态方法❌ 不支持✅ 支持✅ 支持
私有方法❌ 不支持❌ 不支持✅ 支持
私有静态方法❌ 不支持❌ 不支持✅ 支持

🎓 接口要点总结

  1. 接口是完全抽象的类型,定义契约而不关心实现
  2. 支持多重实现,一个类可以实现多个接口
  3. Java 8+ 支持默认方法和静态方法,增强接口能力
  4. Java 9+ 支持私有方法,提高代码复用性
  5. 优先使用接口,需要共享代码时才用抽象类
  6. 接口用于定义"能力",抽象类用于定义"是什么"

记住面向接口编程是Java的重要设计原则,它提高代码的灵活性、可扩展性和可维护性!