Java17密封类增强案例

wen java案例 2

Java 17 密封类(Sealed Classes)增强案例

密封类是Java 17正式引入的一个重要特性,它允许你控制哪些类可以继承或实现某个类/接口,让我通过几个实际案例来展示它的强大功能。

Java17密封类增强案例

基础案例:形状计算系统

// 定义密封接口
public sealed interface Shape permits Circle, Rectangle, Triangle {
    double area();
    double perimeter();
}
// 圆形实现
public final class Circle implements Shape {
    private final 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;
    }
    public double getRadius() {
        return radius;
    }
}
// 矩形实现
public final class Rectangle implements Shape {
    private final double width;
    private final double height;
    public Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }
    @Override
    public double area() {
        return width * height;
    }
    @Override
    public double perimeter() {
        return 2 * (width + height);
    }
    public double getWidth() {
        return width;
    }
    public double getHeight() {
        return height;
    }
}
// 三角形实现
public final class Triangle implements Shape {
    private final double side1;
    private final double side2;
    private final double side3;
    public Triangle(double side1, double side2, double side3) {
        this.side1 = side1;
        this.side2 = side2;
        this.side3 = side3;
    }
    @Override
    public double area() {
        // 使用海伦公式
        double s = (side1 + side2 + side3) / 2;
        return Math.sqrt(s * (s - side1) * (s - side2) * (s - side3));
    }
    @Override
    public double perimeter() {
        return side1 + side2 + side3;
    }
}

与模式匹配结合使用

// Java 17+ 模式匹配与密封类的完美结合
public class ShapeProcessor {
    // 使用模式匹配处理不同形状
    public static String describeShape(Shape shape) {
        return switch (shape) {
            case Circle c -> String.format("圆形,半径: %.2f,面积: %.2f", 
                                          c.getRadius(), c.area());
            case Rectangle r -> String.format("矩形,宽: %.2f,高: %.2f,面积: %.2f", 
                                             r.getWidth(), r.getHeight(), r.area());
            case Triangle t -> String.format("三角形,三边: %.2f, %.2f, %.2f,面积: %.2f", 
                                            t.getSide1(), t.getSide2(), t.getSide3(), 
                                            t.area());
        };
    }
    // 验证形状是否合法
    public static boolean isValidShape(Shape shape) {
        return switch (shape) {
            case Circle c -> c.getRadius() > 0;
            case Rectangle r -> r.getWidth() > 0 && r.getHeight() > 0;
            case Triangle t -> validTriangle(t.getSide1(), t.getSide2(), t.getSide3());
        };
    }
    private static boolean validTriangle(double a, double b, double c) {
        return a > 0 && b > 0 && c > 0 && 
               (a + b > c) && (a + c > b) && (b + c > a);
    }
}

简化中间类继承

// 使用non-sealed允许部分子类开放继承
public sealed class Vehicle permits Car, Truck, Motorcycle {
    private final String brand;
    private final String model;
    public Vehicle(String brand, String model) {
        this.brand = brand;
        this.model = model;
    }
    public String getBrand() {
        return brand;
    }
    public String getModel() {
        return model;
    }
    public abstract double getMaxSpeed();
}
// 使用non-sealed允许进一步继承
public non-sealed class Car extends Vehicle {
    private final int passengerCapacity;
    public Car(String brand, String model, int passengerCapacity) {
        super(brand, model);
        this.passengerCapacity = passengerCapacity;
    }
    @Override
    public double getMaxSpeed() {
        return 250.0;
    }
    public int getPassengerCapacity() {
        return passengerCapacity;
    }
}
// 使用final表示最终类
public final class Truck extends Vehicle {
    private final double loadCapacity;
    public Truck(String brand, String model, double loadCapacity) {
        super(brand, model);
        this.loadCapacity = loadCapacity;
    }
    @Override
    public double getMaxSpeed() {
        return 120.0;
    }
    public double getLoadCapacity() {
        return loadCapacity;
    }
}
// 可以继续继承Car,因为它是non-sealed
public class SUV extends Car {
    private final boolean fourWheelDrive;
    public SUV(String brand, String model, int passengerCapacity, boolean fourWheelDrive) {
        super(brand, model, passengerCapacity);
        this.fourWheelDrive = fourWheelDrive;
    }
    @Override
    public double getMaxSpeed() {
        return 200.0;
    }
    public boolean isFourWheelDrive() {
        return fourWheelDrive;
    }
}

实际业务场景:支付系统

// 支付系统示例
public sealed interface PaymentMethod permits CreditCard, DebitCard, CryptoWallet {
    String getProvider();
    double processPayment(double amount);
}
// 信用卡实现
public final class CreditCard implements PaymentMethod {
    private final String cardNumber;
    private final String expiryDate;
    public CreditCard(String cardNumber, String expiryDate) {
        this.cardNumber = cardNumber;
        this.expiryDate = expiryDate;
    }
    @Override
    public String getProvider() {
        return "Visa/MasterCard";
    }
    @Override
    public double processPayment(double amount) {
        // 信用卡支付逻辑
        double fee = amount * 0.02; // 2%手续费
        return amount + fee;
    }
    public String getCardNumber() {
        return cardNumber;
    }
}
// 借记卡实现
public final class DebitCard implements PaymentMethod {
    private final String bankName;
    private final String accountNumber;
    public DebitCard(String bankName, String accountNumber) {
        this.bankName = bankName;
        this.accountNumber = accountNumber;
    }
    @Override
    public String getProvider() {
        return bankName;
    }
    @Override
    public double processPayment(double amount) {
        // 借记卡支付逻辑
        return amount; // 无额外手续费
    }
    public String getBankName() {
        return bankName;
    }
}
// 加密货币钱包
public final class CryptoWallet implements PaymentMethod {
    private final String walletAddress;
    private final String currency;
    public CryptoWallet(String walletAddress, String currency) {
        this.walletAddress = walletAddress;
        this.currency = currency;
    }
    @Override
    public String getProvider() {
        return "Crypto";
    }
    @Override
    public double processPayment(double amount) {
        // 加密货币支付逻辑
        double fee = amount * 0.001; // 0.1%手续费
        return amount + fee;
    }
    public String getWalletAddress() {
        return walletAddress;
    }
}
// 支付处理器
public class PaymentProcessor {
    public static String processPayment(PaymentMethod method, double amount) {
        return switch (method) {
            case CreditCard cc -> String.format(
                "信用卡支付: 金额=%.2f, 手续费=%.2f, 总计=%.2f, 卡号最后4位=%s", 
                amount, method.processPayment(amount) - amount, 
                method.processPayment(amount), 
                cc.getCardNumber().substring(cc.getCardNumber().length() - 4));
            case DebitCard dc -> String.format(
                "借记卡支付: 金额=%.2f, 手续费=0.00, 总计=%.2f, 银行=%s", 
                amount, method.processPayment(amount), dc.getBankName());
            case CryptoWallet cw -> String.format(
                "加密货币支付: 金额=%.2f, 手续费=%.2f, 总计=%.2f, 币种=%s", 
                amount, method.processPayment(amount) - amount, 
                method.processPayment(amount), cw.getCurrency());
        };
    }
}

测试代码

public class SealedClassDemo {
    public static void main(String[] args) {
        // 测试形状系统
        System.out.println("=== 形状系统测试 ===");
        Shape circle = new Circle(5);
        Shape rectangle = new Rectangle(4, 6);
        Shape triangle = new Triangle(3, 4, 5);
        System.out.println(ShapeProcessor.describeShape(circle));
        System.out.println(ShapeProcessor.describeShape(rectangle));
        System.out.println(ShapeProcessor.describeShape(triangle));
        // 测试支付系统
        System.out.println("\n=== 支付系统测试 ===");
        PaymentMethod creditCard = new CreditCard("1234-5678-9012-3456", "12/25");
        PaymentMethod debitCard = new DebitCard("中国工商银行", "6222021234567890");
        PaymentMethod cryptoWallet = new CryptoWallet("0x1234...", "ETH");
        System.out.println(PaymentProcessor.processPayment(creditCard, 1000));
        System.out.println(PaymentProcessor.processPayment(debitCard, 500));
        System.out.println(PaymentProcessor.processPayment(cryptoWallet, 800));
    }
}

输出结果

=== 形状系统测试 ===
圆形,半径: 5.00,面积: 78.54
矩形,宽: 4.00,高: 6.00,面积: 24.00
三角形,三边: 3.00, 4.00, 5.00,面积: 6.00
=== 支付系统测试 ===
信用卡支付: 金额=1000.00, 手续费=20.00, 总计=1020.00, 卡号最后4位=3456
借记卡支付: 金额=500.00, 手续费=0.00, 总计=500.00, 银行=中国工商银行
加密货币支付: 金额=800.00, 手续费=0.80, 总计=800.80, 币种=ETH

密封类的关键优势

  1. 代码安全性:明确限制继承关系,防止意外扩展
  2. 模式匹配完备性:编译器知道所有子类型,switch表达式不需要default分支
  3. API设计清晰:明确表达类层次结构的完整性和封闭性
  4. 更好的类型安全性:配合模式匹配,减少类型转换错误
  5. 可维护性:代码结构更清晰,易于理解和维护

密封类是Java 17中一个非常实用的特性,特别适合用于领域模型设计、状态机实现和API设计等场景。

抱歉,评论功能暂时关闭!