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

如何用@SuperBuilder和@Data访问作为其他类成员的子类属性?

解决Lombok @SuperBuilder场景下父类类型无法调用子类方法的问题

你的核心问题是City类中定义的Station是父类类型,实际存储的是子类PoliceStation实例,但编译器只识别父类类型,所以无法直接调用子类的特有方法。下面提供几种实用的解决思路:

1. 直接强制类型转换(快速解决)

因为你明确知道getCity()返回的City里的Station是PoliceStation实例,直接强转后就能调用子类方法:

public class Main {
    public static void main(String [] args) {
        City city = getCity();
        // 强转后调用子类的set方法
        ((PoliceStation) city.getStation()).setPoliceStationName("SFPD");
    }
}

如果存在Station是其他子类的可能,建议先做类型检查避免ClassCastException:

if (city.getStation() instanceof PoliceStation) {
    ((PoliceStation) city.getStation()).setPoliceStationName("SFPD");
}

2. 在City类中封装类型安全的方法

在City类里添加专门针对PoliceStation的操作方法,对外提供更友好的接口,同时内置类型检查:

@Data
@SuperBuilder
public class City {
    private String cityName;
    private Station station;

    // 封装设置警局名称的方法
    public void setPoliceStationName(String policeStationName) {
        if (!(station instanceof PoliceStation)) {
            throw new IllegalArgumentException("当前城市的Station不是警局类型");
        }
        ((PoliceStation) station).setPoliceStationName(policeStationName);
    }

    // 可选:封装获取警局名称的方法
    public String getPoliceStationName() {
        return station instanceof PoliceStation ? ((PoliceStation) station).getPoliceStationName() : null;
    }
}

之后在Main里直接调用即可:

public class Main {
    public static void main(String [] args) {
        City city = getCity();
        city.setPoliceStationName("SFPD"); // 无需手动转换,直接调用
    }
}

3. 用泛型让City绑定特定Station子类

通过泛型约束City的Station类型,创建时指定具体子类,这样后续调用无需转换,完全类型安全:

// 修改City类为泛型类
@Data
@SuperBuilder
public class City<T extends Station> {
    private String cityName;
    private T station;
}

// 修改getCity方法,指定泛型类型
public static City<PoliceStation> getCity(){
    return City.<PoliceStation>builder()
        .station(getPoliceStation())
        .cityName("CityName")
        .build();
}

// 在Main中使用
public class Main {
    public static void main(String [] args) {
        City<PoliceStation> city = getCity();
        city.getStation().setPoliceStationName("SFPD"); // 直接调用子类方法,无编译错误
    }
}

这种方式适合业务逻辑中City的Station类型固定的场景。

4. 重构类结构(面向抽象编程)

如果Station的各个子类都有类似的“特有名称”属性,可以在父类中定义抽象方法,让子类实现,这样无需转换就能调用通用方法:

// 修改父类Station,添加抽象方法
@Data
@SuperBuilder
public abstract class Station {
    private String stationName;

    public abstract void setSpecificName(String name);
    public abstract String getSpecificName();
}

// 子类PoliceStation实现抽象方法
@EqualsAndHashCode(callSuper = true)
@Data
@SuperBuilder
public class PoliceStation extends Station{
    private String policeStationName;

    @Override
    public void setSpecificName(String name) {
        this.policeStationName = name;
    }

    @Override
    public String getSpecificName() {
        return this.policeStationName;
    }
}

之后在Main中直接调用父类的通用方法:

public class Main {
    public static void main(String [] args) {
        City city = getCity();
        city.getStation().setSpecificName("SFPD"); // 父类方法调用,适配所有子类
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 16:25:22