discussing some technical aspects covering tools, frameworks, technologies etc (the areas where i m involved and getting experienced) - feel free to discuss!

Monday, January 21, 2008

Getters and Setters for better encapsulation

This is an interesting topic in the beginner's level. Well, at the end of this discussion you would have an answer for these questions.


  1. What are Getters and Setters?

  2. What way they are beneficial?

  3. Are they the means of achieving Encapsulation?

  4. Summary of this encapsulation



Let's take you have a Person object and whose size object is what you are trying to access or set.

The plain version of the class would look like as follows:



class Person
{



public int age;
public String name;




public static void main(String[] args)
{
Person obj1 = new Person();
obj1.age = 5;
obj1.name = "Raghavan";
System.out.println("obj1.age="+obj1.age);
System.out.println("obj1.name="+obj1.name);
}
}



The following program produces the output as:



obj1.age=5
obj1.name=Raghavan



By looking at the above code, you don't seem to get anything strange! Yes so do I :).

Let's have a different scenario on the same class.



class Person
{



public int age;
public String name;




public static void main(String[] args)
{
Person obj1 = new Person();
obj1.age = -5;
obj1.name = "";
System.out.println("obj1.age="+obj1.age);
System.out.println("obj1.name="+obj1.name);
}
}



Now did you see something strange?

If not, look at the two lines carefully.



obj1.age = -5;
obj1.name = "";



They are perfectly valid and legal to the compiler and runtime, they are syntactically correct! But logically?



  • Can any person have a negative age?

  • Can a person's name be empty?




Why these occurred? Because the variables were of public during declaration.

That's why they are allowed outside and any legal value is allowed in the program without any harm.

How we go ahead in preventing this scenario?

Before the setters/getters were in picture or came into existence, the variables were declared public and given outside access without any harms.

In that case,



class Person
{
public int age;




public static void main(String[] args)
{

Person myObj = new Person();
myObj.age = 5;
System.out.println("myObj.age : "+myObj.age);




Person myObj2 = new Person();
/* Check here! */
myObj.age = -2; //Ouch! a syntactically correct but logically incorrect value
System.out.println("myObj2.age : "+myObj2.age);
}
}



Just to have a better control on this value being accessed, there came a rescue in the form of Getters and Setters. As the name indicates, Getter is used to get/obtain a value and Setter is to set a value back. They are also called as Accessor and Mutators.

What if you allowed the access through a method and NOT directly?

For which you need to have two things.


  • First "protect" your variable from outside access. Means, declare them to be of private.

  • Then provide getter and setter for your private variable. As the variable is pricate, the getter and setters should be public.



Following the same, the code will initially look like



class Person
{
private int age;




/* Getter Method */




public int getAge() {
return this.age;
}




/* Setter Method */




public void setAge(int newAge) {
this.age = newAge;
}



public static void main(String[] args)
{
Person myObj = new Person();
//myObj.age = 5; // can't access directly!
myObj.setAge(5);
System.out.println("myObj.age : "+myObj.getAge());




Person myObj2 = new Person();
/* Check here! */
myObj.SetAge(-2); //Ouch! a syntactically correct but logically incorrect value
System.out.println("myObj2.age : "+myObj2.getAge());
}
}



But had you been exposing your code through this way, it would be very easy in a later point when you realize that setting a negative value is a sin! you should NOT allow that, you have an easy way to get rid of it.

Just modify/update the setter method as below :



...
public void setAge(int newAge) {



/* introducing a new check for Age */




if(newAge <=0){ /*definitely age should NOT be zero! */
System.err.println("Invalid age!");
return;
}




this.age = newAge;

}



This way, you really don't break the existing code. As such the users would still continue using your setAge() method to set an age.

Here dealing with the invalid values and the condition to confirm the same may definitely based on the user and requirement. You can either set a default value or throw an exception or just let the user know about invalid value and continue the program normally.

A Quick Summary of encapsulation goes:

Encapsulation reduces coupling between classes, allowing it to make changes to classes without having to change its clients (whoever invokes the methods of this class). This makes maintenance and extension of a software system much easier and less costly.

Remember that for most systems, much more effort is put into maintenance than into initial development, so proper management of code dependencies pays manyfold.




/* 2-arg Constructor */
public Person(int age,String name)
{
this.age = age;
this.name = name;
}



/*Overridden toString() for our Person class*/
public String toString()
{
return "[Person] : age="+this.age+", name="+this.name;
}

4 comments:

kiruthiga said...

That was really good. I knew the purpose of setters n getters b4 reading this article. But there were times when I considered them a mandatory part of the code without realiasing the puropse of it. I got to know the purpose with experience. This is a really good explanation for the beginners.

Raghavan alias Saravanan M said...

@kiruthiga,

Welcome here :) Thanks for those nice words! :)

// I got to know the purpose with experience.//

Glad that the purpose of the blog is saved!

// This is a really good explanation for the beginners.//

Pleasure is mine! :)

Raghavan alias Saravanan M said...

From Bhajan via Local messenger (IPMsg)
========================================
Thanks Raghavan for making it crytal clear to me...

When i sent this question to you i didn't expect that i will get such a beautifully written explanation from you...

Belated wishing you Anniversarry for your this nice doc .. (Jan 21,2008)... :)

-- Bhajan Lal Mehta (THBS).

Raghavan alias Saravanan M said...

@Bhajan,

its my pleasure Bhajan. Glad you found it useful :) Thanks for the wishes :).

About Me

ஏதோ பிறந்தோம், ஏதோ வாழ்ந்தோம் என்றிருப்பதல்ல வாழ்க்கை! எப்படி வாழ்ந்தோம் என்பதும் ஒரு அங்கம். வாழக் கிடைத்த வாழ்க்கையில், ஒரு சிலருக்காவது வசந்தத்தின் முகவரியை அறிமுகம் செய்தோமேயானால் அதுவே வசீகரத்தின் வனப்பைக் கூட்டும்!