面向对象的多对多关系方法

时间:2014-08-06 06:14:03

标签: java arrays class oop

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

通过多对多关系,例如学生 - 主题,每个学生获得某个主题的标记,假设如下:

我希望能够显示给定学生的所有分数。 我想显示来自不同学生的特定科目的所有分数 我希望能够为特定主题更改任何学生的分数。

我在最后一个问题上遇到了麻烦,我似乎无法想出一种方法将这些类相互联系起来,以便在更改时标记保持一致...

这就是我在考虑伪代码时所考虑的事情。假装我们有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 个答案:

答案 0 :(得分:2)

为什么选择这种复杂的类结构。你可以有一个简单的Student class

  class Student{

  String stuName;
  long rollNo;

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

  }

一个Subject class。每个科目都有一些学生注册,以及每个学生在该科目中得分的分数。这可以表示为: -

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
.
.
.
}

  .
  .

}

对于您提到的部分,您想要为某些科目更改学生的分数。您可以在Main方法的类中按字符串名称搜索Subject对象,然后根据name / rollNo更改Student's标记。您可以在Subject类中提供实现此类功能的方法。

答案 1 :(得分: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足以保持科目和成绩之间的映射。

您可能希望在enums in java上阅读更多内容。

答案 2 :(得分:0)

我认为该方法应该与数据库表相同。你应该实施某种类型的加入课程&#34;这些课程应该是单身,你应该在学生和科目中引用它。该类应该有某种列表或地图,或具有该结构的东西,其中包含属性:student,subject,mark。这样你可以通过任何这些属性迭代该集合,这应该做你需要的。此示例How to make SQL many-to-many same-type relationship table适用于数据库,但我认为它应该为您提供一些有用的见解。

答案 3 :(得分:-2)

This article 为在您的设计中包含以下结构提供了一个非常有说服力的案例:

  • 学生(包括结果指针数组)
  • 主题(包括结果指针数组)
  • 结果(包含属于关系的所有属性)

虽然原帖是很久以前的了,但希望这对其他人有帮助。

相关问题