Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setter methods or constructors

so far I have seen two approaches of setting a variable's value in Java. Sometimes a constructor with arguments is used, others setter methods are used to set the value of each variable.

I know that a constructor initialises an instance variable inside a class once a class is instantiated using the "new" Keyword.

But when do we use constructors and when do we use setters?

like image 351
ssayyed Avatar asked Oct 14 '13 11:10

ssayyed


People also ask

Should I use constructor or setters?

You should use the constructor approach, when you want to create a new instance of the object, with the values already populated(a ready to use object with value populated). This way you need not explicitly call the setter methods for each field in the object to populate them.

Can you use a setter in a constructor?

Avoiding setters in constructors makes it clear that the only thing the constructor is doing is setting the instance variable and skipping any other behavior that happens in the setter. No, non-instance methods avoid the trickiness of instance methods, because they don't touch a partly-constructed instance.

What is the point of setter methods?

Getters and setters are used to protect your data, particularly when creating classes. For each instance variable, a getter method returns its value while a setter method sets or updates its value. Given this, getters and setters are also known as accessors and mutators, respectively.


2 Answers

You should use the constructor approach, when you want to create a new instance of the object, with the values already populated(a ready to use object with value populated). This way you need not explicitly call the setter methods for each field in the object to populate them.

You set the value using a setter approach, when you want to change the value of a field, after the object has been created.

For example:-

MyObject obj1 = new MyObject("setSomeStringInMyObject"); // Constructor approach // Yippy, I can just use my obj1, as the values are already populated // But even after this I can change the value obj1.setSomeString("IWantANewValue"); // Value changed using setter, if required. .. MyObject obj2 = new MyObject(); obj2.setSomeString("setSomeStringNow"); // Setter approach // values weren't populated - I had to do that. Sad :( 

And as Axel mentioned, if you want to create immutable objects, you cannot use setter-methods approach. I won't say everything has to be initialised in the constructor because different approaches exist, like lazy-evaluation which can be used even with immutable objects.

like image 152
Rahul Avatar answered Sep 18 '22 00:09

Rahul


I think you asked a good question: - But when do we use constructors and when do we use setters?

First, let's start with some concepts. I hope this explanation helps everybody that want to know when to use constructors or setters() and getters() methods (Accessors and Mutators). Constructors are similar to Methods, however there are few differences between constructor and method in java:

1) Constructor is used to initialize the state of an object. Method is used to expose behaviour of an object.

2) Constructor must not have return type. Method must have return type.

3) Constructor is invoked implicitly. Method is invoked explicitly.

4) Getters(), or accessors, are methods that provide access to an object's instance variables. Setters(), or mutators, are methods that provide the caller with an opportunity to update the value of a particular instance variable.

Having this clear, let's think in term of Object Oriented Programming (OOP), to meet the requirement of OOP principals (The Objects Oriented Programming (OOP) is constructed over four major principles: Encapsulation, Data Abstraction, Polymorphism and Inheritance.), Getter() and Setter() methods is the key to achieve this.

Here is a formula that is going to show you what I mean:

Private fields + Public accessors == Encapsulation;

As you can see based on this formula when we set private fields and use public accesors we are performing encapsulation one of the 4 OOP principals.

Here I am going to provide you two classes, I added comment on it to try to make my code self explaining. Take these classes as a lab on methods with Customer and TestCustomer [the one with the main() method] classes, you can copy the code and run it yourself. Note I used two constructors in order to explain a class having multiple constructors and having public setters() and getters() methods in order to access private instance variables:

package com.exercise.lecture2;  /**  * 1) Create a Customer class that has the following attributes:  * name, SSN.  * 2) This class should have two methods: getName() and getSSN().  * 3) If the class is instantiated with only a SSN, then give the default name of "John Doe". (HINT: Use two constructors)  * 4) Also, add a method toString(), that returns a string representation of the customer object (name and SSN concatenated).  *      Make sure to set this method public.  * 5) Create a class to test your program (e.g. a class that include the main() method). In your test program, instantiate  *      three customers and print out the value using toString() method.  *   * @author Samuel M.  *  */  //this class is complemented with class  TestLabCustomer.java public class LabCustomer {  // Private filds: name and socialSecurityNum     private String name;     private int socialSecurityNum;      // constructors     public LabCustomer(String name, int socialSecurityNum) {         this.name = name;         this.socialSecurityNum = socialSecurityNum;     }      /** The keyword 'this' can be used to call a constructor from a constructor,      * when writing several constructor for a class, there are times when      * you'd like to call one constructor from another to avoid duplicate code.      */     // Account with This() on a second constructor     public LabCustomer(int socialSecurityNum) {         this("John Doe", socialSecurityNum); // default name is printed if only the SSN is provided     }      // Public accessors (getters and setters)     String getName() {         return name;     }      void setName(String name) {         this.name = name;     }      int getSSN() {         return socialSecurityNum;     }      void setSSN(int socialSecurityNum) {         this.socialSecurityNum = socialSecurityNum;     }       // instance method     public String toString() { //overriding the toString() method          return ("Customer name: " + getName() + ", SSN#: " + getSSN() ); // concatenating the name and SSN      } } 

Here is the test class, the one that has the main() method and calling an instance method after instantiating an object of the previews class:

package com.exercise.lecture2;  //this class is complemented with class  LabCustomer.java public class TestLabCustomer {      public static void main(String[] args) {         // Instantiating an object of class LabCustomer and creating three customers objects         LabCustomer cust1 = new LabCustomer("Juan Melendez", 123457789);         LabCustomer cust2 = new LabCustomer("Mary Lee", 125997536);         LabCustomer cust3 = new LabCustomer(124963574); // when instantiating with no "name", the default (John Doe) is printed           /**          * Once you've instantiated an object and have an object variable,          * you can use object variable to call an instance method.           *  e.g.:          *  object variables: cust1, cust2, cust3          *  call the method toString() using the object variable and dot [.] in order to perform the method call.          */         // calling method toString() in class LabCustomer to print customer values         System.out.println(cust1.toString());         System.out.println(cust2.toString());         System.out.println(cust3.toString());      }  } 

result:

Customer name: Juan Melendez, SSN#: 123457789

Customer name: Mary Lee, SSN#: 125997536

Customer name: John Doe, SSN#: 124963574

like image 36
S. Mayol Avatar answered Sep 18 '22 00:09

S. Mayol