Grading students: proper encapsulation I am discussing with one of my peers about proper encapsulation. We had to write this code. One of the specifications is: "The Student object has to have a Grade object called finalGrade. Code hint: Grade finalGrade;"

This is my code

public class Student
{
  private String firstName;
  private String lastName;
  private String id;

  public Grade finalGrade = new Grade(); // THIS IS THE QUESTIONABLE CODE
...
...
}

public class TestStudent
{

  public static void main(String[] args)
  {
   ...
   ...
   ...
    student.finalGrade.setGradeValue(85);   
    student.finalGrade.setLetterGrade('B');
    student.setFinalGrade('B');

    System.out.println(student.finalGrade.getGradeValue()); 
    System.out.println(student.finalGrade.getLetterGrade());
  }
}


This is their code

public class Student {
...
Grade finalGrade;  // THIS IS THE QUESTIONABLE CODE
public Grade getFinalGrade() {
return finalGrade;
}

public void setFinalGrade(Grade finalGrade) {
this.finalGrade = finalGrade;
}

....
public String toString() {
String display = String.format("Student: id= %d name= %s letterGrade = %s", ID, getName(), finalGrade );
return display;
}
}

public class TestStudent {
public static void main(String[] argv) {
...
...
Grade g = new Grade();
g.setGradeValue(85);
g.setLetterGrade('B');
s.setFinalGrade(g);
System.out.println(s.toString());
}
}


Ultimately, which code is better given the specification?  My argument is that finalGrade is a class and should be accessed with the dot operator. My peer states that it is an attribute and should be private. I see it as a class accessing a class such as SuperClass.class.method();
One of the most important concept of Object Oriented Programming (and programming in general) is information hiding and encapsulation. A class should never expose its attributes unless there are some very valid reasons to do so (for example to share a constant). The fields of a class should be made available providing getters and setters. The reasons of that are many. For example if you have that field finalGrade public and a day you will want to change some details of that field, e.g. use a subclass of Grade, you will cause a long cascade of errors wherever you made a reference to that object without a getter method. We could spend a lot of time talking about how information hiding is important in OOP, but in short...your peer is right!