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

接口Setter实现与训练会话对象存入ArrayList技术咨询

Java编程任务问题解答:接口实现与泛型集合优化

嘿,我来帮你搞定这两个Java编程问题,咱们一个个捋清楚:


问题1:接口实现与TrainingsessionWithGoal构造方法的正确写法

你当前直接在构造方法里给caloryGoal赋值的写法能运行,但不是最规范的实现方式,具体得看你的接口设计逻辑:

如果你的setCaloryGoal方法只是简单的赋值,直接写this.caloryGoal = caloryGoal没问题;但如果后续你想给卡路里目标加校验逻辑(比如不能为负数、不能超过某个上限),直接赋值就会跳过这些校验,导致数据不合法。

更优的做法是调用接口的setCaloryGoal方法,这样能保证所有设置卡路里目标的逻辑统一,后续修改校验规则时也不用改构造方法。

给你一个完整的实现示例:

首先定义接口(假设接口名为CaloryGoalAware):

public interface CaloryGoalAware {
    void setCaloryGoal(int caloryGoal);
    int getCaloryGoal();
    double getAchievementDegree();
}

然后实现TrainingsessionWithGoal类:

public class TrainingsessionWithGoal extends Trainingsession implements CaloryGoalAware {
    private int caloryGoal;

    // 构造方法中调用接口的set方法,而不是直接赋值
    public TrainingsessionWithGoal(int trainingtime, Fitnessdevice fitnessdevice, int day, int month, int year, int hh, int mm, int caloryGoal) {
        super(trainingtime, fitnessdevice, day, month, year, hh, mm);
        setCaloryGoal(caloryGoal); // 这里调用set方法,统一逻辑
    }

    @Override
    public void setCaloryGoal(int caloryGoal) {
        // 这里可以加参数校验,比如禁止负数目标
        if (caloryGoal <= 0) {
            throw new IllegalArgumentException("卡路里目标必须大于0");
        }
        this.caloryGoal = caloryGoal;
    }

    @Override
    public int getCaloryGoal() {
        return caloryGoal;
    }

    @Override
    public double getAchievementDegree() {
        // 假设父类Trainingsession有getCaloriesBurned()方法获取已消耗卡路里
        int burnedCalories = getCaloriesBurned();
        return (double) burnedCalories / caloryGoal;
    }
}

这种写法的好处是:所有设置卡路里目标的入口都经过setCaloryGoal,逻辑统一,后续维护起来更省心。


问题2:TrainingProgramm类的集合泛型正确使用方式

你用ArrayList<Objects>的问题在于:每次取元素都要强制类型转换,不仅麻烦,还容易出现ClassCastException,完全没利用Java的类型安全特性。

正确的思路是利用多态:因为TrainingsessionWithGoal是Trainingsession的子类,所以可以用ArrayList<Trainingsession>来存储这两种对象,既保证类型安全,又能灵活兼容子类。

给你修改后的代码:

import java.util.ArrayList;

public class TrainingProgramm {
    private String programmName;
    private ArrayList<Trainingsession> trainingSessions;

    // 两种构造方式:初始化空列表,或者接收已有的训练会话列表
    public TrainingProgramm(String programmName) {
        this.programmName = programmName;
        this.trainingSessions = new ArrayList<>();
    }

    public TrainingProgramm(String programmName, ArrayList<Trainingsession> trainingSessions) {
        this.programmName = programmName;
        this.trainingSessions = trainingSessions;
    }

    // 添加训练会话的方法,支持普通会话和带目标的会话
    public void addTrainingSession(Trainingsession session) {
        trainingSessions.add(session);
    }

    // 获取所有训练会话
    public ArrayList<Trainingsession> getTrainingSessions() {
        return trainingSessions;
    }
}

使用示例:

// 创建普通训练会话
Trainingsession normalSession = new Trainingsession(60, new Fitnessdevice("跑步机"), 1, 10, 2024, 10, 0);
// 创建带目标的训练会话
TrainingsessionWithGoal goalSession = new TrainingsessionWithGoal(45, new Fitnessdevice("椭圆机"), 2, 10, 2024, 14, 30, 500);

// 创建训练计划并添加会话
TrainingProgramm program = new TrainingProgramm("秋季减脂计划");
program.addTrainingSession(normalSession);
program.addTrainingSession(goalSession);

// 遍历时可以用instanceof区分类型
for (Trainingsession session : program.getTrainingSessions()) {
    if (session instanceof TrainingsessionWithGoal) {
        TrainingsessionWithGoal goalSessionCast = (TrainingsessionWithGoal) session;
        System.out.println("训练完成度:" + goalSessionCast.getAchievementDegree());
    }
    // 处理普通训练会话的逻辑
}

这样既避免了类型转换的风险,代码可读性也更高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:34:34