如何为不同Student记录对应Course的独立进度?Java类设计问题
问题分析与解决方案
你的核心问题是把「学生的课程进度」错误地绑定到了Course类上。当前Course里的percentage是课程实例的全局属性,所有选这门课的学生共享同一个进度值——所以John修改后,Mike看到的也是同一个数值,这完全违背了「每个学生的课程进度独立」的需求。进度本质是「学生-课程」这个组合的属性,不是课程单独的属性。
下面给出两种可行的修复方案:
方案一:新增选课关联类(Enrollment)
创建专门的类来记录学生与课程的绑定关系,以及对应进度,让每个学生的每门课进度完全独立。
1. 新增Enrollment类
public class Enrollment { private Student student; private Course course; private int progress; public Enrollment(Student student, Course course) { this.student = student; this.course = course; this.progress = 0; } public void addProgress(int amount) { this.progress += amount; } public int getProgress() { return this.progress; } public Course getCourse() { return course; } }
2. 修改Student类
把原有的课程列表替换为选课记录列表,所有进度操作都基于Enrollment:
import java.util.ArrayList; import java.util.Optional; public class Student { private String name; private ArrayList<Enrollment> enrollments; public Student(String name) { this.name = name; this.enrollments = new ArrayList<>(); } // 学生选课,生成对应的进度记录 public void enrollCourse(Course course) { this.enrollments.add(new Enrollment(this, course)); } public void seeCourses() { for (Enrollment enrollment : enrollments) { System.out.println(enrollment.getCourse()); } } public void addProgress(Course course, int amount) { // 找到对应课程的选课记录 Optional<Enrollment> enrollmentOpt = enrollments.stream() .filter(e -> e.getCourse().equals(course)) .findFirst(); if (enrollmentOpt.isPresent()) { enrollmentOpt.get().addProgress(amount); } else { System.out.println("学生未选该课程"); } } public int seeProgress(Course course) { Optional<Enrollment> enrollmentOpt = enrollments.stream() .filter(e -> e.getCourse().equals(course)) .findFirst(); // 没选的课程返回0 return enrollmentOpt.map(Enrollment::getProgress).orElse(0); } }
3. 测试用Main类
注意要先让学生选课,再操作进度:
public class Main { public static void main(String[] args) { Course programming = new Course("Programming"); Course english = new Course("English"); Student john = new Student("John"); Student mike = new Student("Mike"); // John选English课,Mike不选 john.enrollCourse(english); john.addProgress(english, 20); System.out.println("John's progress: " + john.seeProgress(english)); System.out.println("Mike's progress: " + mike.seeProgress(english)); } }
方案二:在Student类中用Map存储课程进度映射
如果不想新增类,可以直接用Map<Course, Integer>在学生内部保存每门课的进度,实现更简洁:
修改后的Student类
import java.util.ArrayList; import java.util.HashMap; import java.util.Map; public class Student { private String name; private ArrayList<Course> courses; private Map<Course, Integer> courseProgress; public Student(String name) { this.name = name; this.courses = new ArrayList<>(); this.courseProgress = new HashMap<>(); } public void addCourse(Course course) { this.courses.add(course); // 新增课程时初始化进度为0 courseProgress.putIfAbsent(course, 0); } public void seeCourses() { for (Course i : courses) { System.out.println(i); } } public void addProgress(Course course, int amount) { if (courseProgress.containsKey(course)) { courseProgress.put(course, courseProgress.get(course) + amount); } else { System.out.println("学生未选该课程"); } } public int seeProgress(Course course) { // 没选的课程默认返回0 return courseProgress.getOrDefault(course, 0); } }
测试用Main类
public class Main { public static void main(String[] args) { Course programming = new Course("Programming"); Course english = new Course("English"); Student john = new Student("John"); Student mike = new Student("Mike"); // John添加English课程,Mike不添加 john.addCourse(english); john.addProgress(english, 20); System.out.println("John's progress: " + john.seeProgress(english)); System.out.println("Mike's progress: " + mike.seeProgress(english)); } }
运行结果
两种方案都会输出预期结果:
John's progress: 20 Mike's progress: 0
内容的提问来源于stack exchange,提问作者Ordinary
相关产品推荐
相关产品推荐

