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

如何实现支持多类型运动员的泛型Team类与compete方法?

解决方案:类型安全的泛型Team类实现

这个问题的核心是要在保证类型安全的前提下,让同一个Team类既能处理不同类型的运动员,又能自动执行对应的跑步或跳远动作。结合泛型多重约束和函数式接口,我们可以优雅地解决这个需求:

第一步:补充Athlete类的Getter方法

原代码中Athlete的字段都是私有且没有对外暴露的方法,我们需要添加getter来获取运动员的基本信息:

public class Athlete { 
    private final int id; 
    private final String name; 
    private final Country sourceCountry; 
    public Athlete(int id, String name, Country sourceCountry){ 
        this.id = id; 
        this.name = name; 
        this.sourceCountry = sourceCountry; 
    } 

    // 添加必要的getter方法
    public int getId() { return id; }
    public String getName() { return name; }
    public Country getSourceCountry() { return sourceCountry; }
}

// 假设你的Country类是这样的(如果还没定义)
public class Country {
    private final String name;
    public Country(String name) { this.name = name; }
    public String getName() { return name; }
}

第二步:实现泛型Team类

我们通过静态工厂方法来约束不同队伍可容纳的运动员类型,同时传入对应的竞争动作函数,确保compete方法能正确执行跑步或跳远:

import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;

public class Team<C extends Athlete> {
    private final List<C> members = new ArrayList<>();
    private final Function<C, Double> competitionAction;

    // 私有构造方法,强制通过静态工厂创建实例
    private Team(Function<C, Double> competitionAction) {
        this.competitionAction = competitionAction;
    }

    // 创建跑步队:仅允许添加实现IRunner的Athlete(Runner和RunnerJumper)
    public static <C extends Athlete & IRunner> Team<C> createRunningTeam() {
        return new Team<>(IRunner::run);
    }

    // 创建跳远队:仅允许添加实现IJumper的Athlete(Jumper和RunnerJumper)
    public static <C extends Athlete & IJumper> Team<C> createJumpingTeam() {
        return new Team<>(IJumper::jump);
    }

    // 添加队员(类型安全,不符合约束的运动员无法添加)
    public void addMember(C member) {
        members.add(member);
    }

    // 执行比赛:遍历队员并执行对应的动作
    public void compete() {
        for (C member : members) {
            double score = competitionAction.apply(member);
            System.out.printf("运动员 %s(ID:%d,来自%s)的成绩:%.2f%n",
                    member.getName(), member.getId(), member.getSourceCountry().getName(), score);
        }
    }
}

第三步:使用示例

现在你可以创建不同类型的队伍,并添加符合要求的运动员:

public class Main {
    public static void main(String[] args) {
        // 创建跑步队,添加Runner和RunnerJumper
        Team<Runner> runningTeam = Team.createRunningTeam();
        runningTeam.addMember(new Runner(1, "张三", new Country("中国")));

        Team<RunnerJumper> multiRunningTeam = Team.createRunningTeam();
        multiRunningTeam.addMember(new RunnerJumper(2, "李四", new Country("美国")));

        // 创建跳远队,添加Jumper和RunnerJumper
        Team<Jumper> jumpingTeam = Team.createJumpingTeam();
        jumpingTeam.addMember(new Jumper(3, "王五", new Country("英国")));

        Team<RunnerJumper> multiJumpingTeam = Team.createJumpingTeam();
        multiJumpingTeam.addMember(new RunnerJumper(4, "赵六", new Country("法国")));

        // 执行比赛
        System.out.println("=== 跑步比赛结果 ===");
        runningTeam.compete();
        multiRunningTeam.compete();

        System.out.println("\n=== 跳远比赛结果 ===");
        jumpingTeam.compete();
        multiJumpingTeam.compete();
    }
}

方案优势

  1. 类型安全:通过泛型多重约束(C extends Athlete & IRunner),编译器会自动阻止你向跑步队添加非跑步运动员,向跳远队添加非跳远运动员。
  2. 代码复用:同一个Team类可以处理跑步和跳远两种场景,无需编写重复的类。
  3. 灵活扩展:如果后续新增其他运动类型(比如游泳),只需要添加对应的运动接口,再新增一个静态工厂方法即可,无需修改现有Team类的核心逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 14:32:56