Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setter method in constructor

Got a question that I come across

public class Student{
     private String studentNumber;
     private String studentName;
     private double studentResult;

     public Student (String aNumber, String aName){
         setStudentNumber(aNumber);
         setStudentName(aName);
         setStudentResult(0);
     }
     // The standard getter and setter method are define here.
}

what is the purpose of having the setter method in the constructor? and with the setStudentResult(0), do we need to have another instance variable?

like image 992
i-link Avatar asked Apr 23 '13 11:04

i-link


4 Answers

Calling overridable methods is an anti-pattern, it may cause problems if Student is overridden. A good pattern would be to make Student immutable

public class Student{
    private final String studentNumber;
    ...
    public Student (String studentNumber, ...) {
       this.studentNumber = studentNumber;
    ...
like image 93
Evgeniy Dorofeev Avatar answered Nov 02 '22 19:11

Evgeniy Dorofeev


The usual purported reason for setters in a constructor is so that you are using the same validation. However, self-encapsulation is an anti-pattern.

A much better for doing exactly what you have written is to have a static method which constructs the object and calls the set methods. Much better than that would be to make the whole thing immutable.

like image 35
Tom Hawtin - tackline Avatar answered Nov 02 '22 21:11

Tom Hawtin - tackline


Are you doing any business logic in your setter methods. If yes i guess that's the reason you call setter from constructor. If you are just seeting your instance variable inside your setter, then setting the instance variable directly is the normal thing to do.

public class Student{
private String studentNumber;
private String studentName;
private double studentResult;

public Student (String aNumber, String aName){
this.studentNumber = aNUmber;
this.studentName=aName;
this.studentResult=0;
}
like image 34
PermGenError Avatar answered Nov 02 '22 21:11

PermGenError


You will have to use above code practice when you are dealing with validation of sent(which you are sending) value.
For example, if you don't want to allow any negative number to be set as a studentNUmber from the constructor then you have to write a logic to check the number either inside constructor or inside method depending on whether the class is immutable or mutable. If class is mutable then write logic inside method and if the class is immutable then write logic inside constructor(in immutable class writing setter method is not allowed because setter method can change the state of the object).
If you don't apply such logic then any negative value can be set to studentNumber.

Also, setter methods are useful when you have an object created in some other class and later you want to change it's state, say, you want to update the name of student, like given example below,

public class Student {
    private String studentNumber;
    private String studentName;
    private double studentResult;
    // The standard getter and setter method are define here.

    public Student(String aNumber, String aName) {
        studentNumber = aNumber;
        studentName =aName;
    }

    public String getStudentNumber() {
        return studentNumber;
    }

    public void setStudentNumber(String studentNumber) {
        this.studentNumber = studentNumber;
    }

    public String getStudentName() {
        return studentName;
    }

    public void setStudentName(String studentName) {
        this.studentName = studentName;
    }

    public double getStudentResult() {
        return studentResult;
    }

    public void setStudentResult(double studentResult) {
        this.studentResult = studentResult;
    }

    @Override
    public String toString() {
        return "studentNumber:"+studentNumber+", studentName"+studentName+", studentResult"+studentResult;
    }

}

class Test {
    public static void main(String[] args) {
        Student s = new Student("1", "AAA");
        s.setStudentName("BBB"); //we should call this method because of "studentName" is private variable in Student class.
        System.out.println(s);
    }
}

about setStudentResult, you need not to have yet another instance variable as it is already declared in the Student class. Instead you need add one more parameter in the constructor to setStudentResult value.

public Student(String aNumber, String aName, long result) {
        studentNumber = aNumber;
        studentName =aName; 
        studentResult =result;
    }
like image 27
AmitG Avatar answered Nov 02 '22 19:11

AmitG