Setter为类中的每个对象设置值

问题描述 投票:0回答:4

我有一个程序,它将学生的姓名和成绩作为用户输入,然后对它们执行一些操作,这与问题的范围无关。代码如下:

import java.io.*;
import java.util.Arrays;
import java.util.Scanner;

public class Student {
// Four attributes that define Student
private String name;
private double points;
private int startYear;
private int[] grades;

public Student(String name, double points, int startYear, int[] grades) {
    this.name = name;
    this.points = points;
    this.startYear = startYear;
    this.grades = grades;
}
//Constructor. Everyone starts with 0 points and this year

public static void main(String[] args) {
    Scanner sc = new Scanner(System.in); //Create scanner
    System.out.println("Please enter the number of students:");
    int count = sc.nextInt(); // Number of students
    System.out.println("Please enter the number of grades:");
    int count1 = sc.nextInt(); // Number of grades
    Student students[] = new Student[count]; // Create array of student objects based on previously entered value
    int[] temp = new int[count1]; // Temporary array for storing grades entered
    for (int i = 1; i < count + 1; i++) {
        System.out.println("Please enter the name of student " + i);
        String name = sc.next();
        students[i - 1] = new Student(name,0.0,2018,temp); // Creating student object
        System.out.println("Please enter grades of  " + name);
        for (int k = 0; k < count1; k++) {
            int personal_grades = sc.nextInt();
            temp[k] = personal_grades; //filling the temporary array
            //System.out.println(grades.length); //for debugging

        }
        students[i - 1].setGrades(temp); //transferring from temporary array to student object array
        students[i-1].printGrades();

    }
    System.out.println((students[0].name));
    System.out.println((students[1].name));
    System.out.println(Arrays.toString(students[0].grades));
    System.out.println(Arrays.toString(students[1].grades));
    for(int i = 0; i < count; i++) {
        System.out.println("Grades of  " + students[i].name + " are:");
        //students[i].printGrades();
    }
    for(int i = 0; i < count; i++) {
        System.out.println("Average of  " + students[i].name + " is:");
       // students[i].average();
    }
    int passed=0;
    for(int i = 0; i < count; i++) {

        if(students[i].average()>5.5)
        {
            passed++;

        }

    }
    System.out.println(passed+" students passed!");


}

public void setGrades(int[] temp) {

        this.grades = temp;


}

public int[] getGrades() {
    return grades;
}

public void printGrades() {


        System.out.println(Arrays.toString(grades));

    }

public float average (){
    int k = 0;
    int sum=0;
    float average=0;
    while (k < this.grades.length) {
        sum=sum+this.grades[k];
       k++;

    }
    average = sum/(float)this.grades.length;
    System.out.println(average);
    return average;
}
}

我对代码的问题如下:setter方法似乎设置了所有创建的对象的值。以此测试运行为例:enter image description here

您可以看到输入的最后一个学生的成绩出现在每个学生的记录中。我已经调试并发现它是导致这种情况的setGrades方法。但是,我使用的是this关键字 - 为什么它会为所有对象设置值呢?

java setter
4个回答
1
投票

你需要移动

int[] temp = new int[count1]; // Temporary array for storing grades entered

在外部for循环内,否则所有创建的Students将引用相同的成绩数组,并且最终将获得最后一个学生的成绩。


0
投票

这是因为你对所有人的等级使用相同的数组。

在第一个循环中移动temp = new int[count1];应该修复它


0
投票

请注意Student的构造函数和Student::setGrades()如何通过引用获得grades

这意味着对于每个Student的实例,其grades字段指向在其初始化期间接收的参数。

但是,您只初始化temp一次,因此所有实例都指向相同的grade数组。更改此数组后,调用student.printGrades()将打印共享数组的内容。

这可以通过在创建新的temp实例之前在每次迭代时初始化Student来解决;或者通过setGrades()方法中的值复制数组:

public void setGrades(int[] temp) {
    this.grades.clone(temp);
}

0
投票

移动数组(temp),将成绩保留在创建单个学生的循环中

for (int i = 1; i < count + 1; i++) {
    ...
    int[] temp = new int[count1];  //The array holding the grades must be *specific* for each student

    students[i - 1] = new Student(name, 0.0, 2018, temp); // Creating student object
    ...
    students[i - 1].setGrades(temp); //transferring from temporary array to student object array
    students[i - 1].printGrades();

}

在原始代码中,您只使用一个数组i。,e temp始终指向同一个数组。初始化完第一个学生后,当您循环填充第二个学生的成绩时,您正在改变(或修改)为第一个学生创建的相同成绩数组。

© www.soinside.com 2019 - 2024. All rights reserved.