面向对象的方式处理多对多关系

4

我目前正努力理解如何以面向对象的方式解决这个问题。

例如学生-科目这样的多对多关系,每个学生都会得到某一门课程的成绩,假设以下情况:

我想要显示某个学生的所有成绩。 我想要显示给定科目不同学生的所有成绩。 我想要能够更改某个学生在某个科目上的成绩。

我遇到了最后一个问题,似乎无法想到一种方法将类相互关联,以便更改时成绩保持一致...

以下是我考虑使用的伪代码。 假设我们有3名学生,每个学生参加3门课程(共9个成绩):

Make a class for Student (String name, int studNumber)

Make a class for Subject (String name, int subNumber)

Make a class for Result(int percentageScore String grade(calculated based on
percentageScore)) 

Then have an array of arrays of Result objects, eg. [1][2] in the array will 
give the score for the student with studNumber 2 in the subject with subNumber 1.   

我感觉这不是面向对象的?学科和学生之间的关系应该在类设计中得到认可。如果我的想法是正确的,有人能指点一下我吗?如何以面向对象的方式实现这一点呢?

非常感谢。

4个回答

2
为什么要使用如此复杂的类结构?你可以只使用一个简单的 Student 类
  class Student{

  String stuName;
  long rollNo;

  public Student(String stuName, long rollNo){
   this.stuName=stuName;
   this.rollNo=rollNo;
   }
   .
   .
   .

  }

以及一个Subject类。每个科目有一定数量的已注册学生和每个学生在该科目中获得的分数。可以表示为:

class Subject{

String subName;
HashMap<Integer,Student> Result;

public Subject(String subName){
this.subName=subName;
Result=new HashMap<Integer,Student>();
}

//add methods to add students,modify marks, etc

public void addStudent(String name,long roll, int marks){


Result.put(marks,new Student(name,roll));

}

public int giveMarksForSubject(long roll){

//iterate Results , and check for student objects to match roll no. return key of matching student
.
.
.
}

  .
  .

}

当你提到想要更改某个学生在某个科目的分数时,你可以在主方法的类中通过字符串名称搜索科目对象,然后根据姓名/学号更改学生的分数。你可以在Subject类中提供方法来实现这样的功能。


1

因为科目和成绩的取值都是有限的,所以我建议使用枚举类型:

public class Example {

    public static void main(String[] args) throws IOException {
        Student s1 = new Student("John Doe");
        s1.setGrade(Subject.MATHS, Grade.B);
        s1.setGrade(Subject.PHYSICS, Grade.A);
        s1.setGrade(Subject.ENGLISH, Grade.E);

        Student s2 = new Student("Jane Smith");
        s2.setGrade(Subject.MATHS, Grade.C);
        s2.setGrade(Subject.PHYSICS, Grade.C);
        s2.setGrade(Subject.ENGLISH, Grade.A);

        // print students and their grades:
        s1.printAllGrades();
        s2.printAllGrades();

        // print every subject and its grades:
        for(Subject s : Subject.values()){
            s.printAllGrades();
        }
    }
}

enum Subject{
    MATHS, PHYSICS, ENGLISH;

    private Map<Student, Grade> grades = new HashMap<Student, Grade>();

    public void setGrade(Student student, Grade grade){
        grades.put(student, grade);
    }

    public void printAllGrades(){
        System.out.println(this);
        for(Student s : grades.keySet()){
            System.out.println(s.getName() + " : " + grades.get(s));
        }
    }
}

enum Grade{ 
    A, B, C, D, E, F
}

class Student{

    private String name;
    private Map<Subject, Grade> grades = new HashMap<Subject, Grade>();

    public Student(String name){
        this.name = name;
    }

    public String getName(){
        return this.name;
    }

    public void setGrade(Subject subject, Grade grade){
        grades.put(subject, grade);
        subject.setGrade(this, grade);
    }

    public Grade getGrade(Subject subject){
        return grades.get(subject);
    }

    public void printAllGrades(){
        System.out.println("Grades of " + name + ":");
        for(Subject s : grades.keySet()){
            System.out.println(s + " : " + grades.get(s));
        }
    }

}

使用枚举类型适合列出科目和成绩。它保证只有合适的值可以作为参数传递,并且易于扩展 - 如果您希望,可以向枚举添加方法。每个学生的简单HashMap足以保存科目和成绩之间的映射关系。
您可能想阅读更多关于Java中的枚举的内容,请参考enums in java

0

我认为处理方式应该与数据库表格相同。在这两者之间,您应该实现某种“连接类”。该类应该是单例的,并且您应该在学生和科目中引用它。该类应该有一些列表或映射,或具有该结构的其他内容,其中应包含属性:学生、科目、成绩。这样,您可以通过任何这些属性之一迭代该集合,从而实现您所需的功能。虽然这个如何制作SQL多对多相同类型关系表是针对数据库的,但我认为它应该会给你一些有帮助的见解。


-2

这篇文章非常有说服力,建议你在设计中包含以下结构:

  • 学生(包括一个结果指针数组)
  • 科目(包括一个结果指针数组)
  • 结果(包括属于关系的所有属性)

尽管原始帖子是很久以前的,但希望这对其他人有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接