接口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
相关产品推荐
相关产品推荐

