You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java结合流式接口与策略模式时如何让父类方法返回子类实例

问题根因

当前抽象父类Foo仅声明了数据类型的泛型参数,没有将子类自身的类型纳入泛型约束,导致父类中定义的方法只能固定返回Foo<T>类型,子类调用完父类方法后会丢失自身类型,无法继续调用子类自定义的方法。

改造方案

通过给父类增加自限定的子类泛型参数即可解决,具体修改步骤如下:

步骤1:改造抽象父类Foo

新增泛型参数S指代实际子类类型,修改方法返回值为S:

// 新增S泛型,约束为继承自Foo<T, S>,指向实际实现类
public abstract class Foo<T extends BarData, S extends Foo<T, S>> {
    T data;

    public Foo(T data) {
        this.data = data;
    }

    // 修正方法签名缺的括号,返回值改为S
    public S fooMethod() {
        // 原有业务逻辑
        return (S) this;
    }
}

此处的强转是安全的,泛型约束已经保证了this必然是S类型的实例。

步骤2:修改子类继承逻辑

子类继承Foo时,将自身作为泛型参数S传入:

public class Bar extends Foo<BarData, Bar> {

    public Bar(BarData data) {
        super(data);
    }

    public Bar barMethod() {
        // 原有业务逻辑
        return this;
    }
}

步骤3:对齐接口与实现类定义

修正原代码中接口名不一致、方法修饰符缺失的问题:

// 统一接口名,泛型对齐父类定义
public interface FluentInterface<T extends BarData, S extends Foo<T, S>> {
    S initialize();
}

// 实现类对齐接口名,补充方法public修饰符
public class BasicFluentInterfaceImplementation implements FluentInterface<BarData, Bar> {
    @Override
    public Bar initialize() {
        // 原有准备数据逻辑
        BarData data = new BarData();
        return new Bar(data);
    }
}

步骤4:修正调用代码

不要使用原始类型的FluentInterface,否则会丢失泛型信息:

public class Main {
    public static void main(String[] str) {
        // 明确指定泛型参数,避免类型擦除
        FluentInterface<BarData, Bar> api = new BasicFluentInterfaceImplementation();
        
        // 链式调用全程保留Bar类型,可正常调用所有方法
        api.initialize()
           .fooMethod()
           .barMethod();
    }
}
补充说明

该方案是Java实现流式接口的通用写法,后续新增任意Foo的子类,只要继承时将自身作为泛型参数传入,即可直接复用父类的流式调用能力,无需修改父类逻辑。

内容的提问来源于stack exchange,提问作者Toniotti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 04:18:02