Reputation: 117
I have a bit of confusion with encapsulation concept. I have gone through quite a few answers on the same , but still confused. As far as I understand, encapsulation is to make instance variables as private so that outside cannot access this directly. Public getter and setter methods would be provided to access the private variables.
Suppose we have a class like below :
class Address
{
int doorNumber;
public int getDoorNumber()
{
//some code
}
public void setDoorNumber(int doorNumber)
{
//some code
}
}
We have another class from which we are trying to access the variable of Address class.
class TestAddress
{
public static void main()
{
Address add=new Address();
add.doorNumber=10; //cannot be done
add.setDoorNumber(10);
}
}
Though we are not accessing the variable directly , we are still modifying doorNumber
using setter method to set the value of it to 10 . Basically the outside world can still access the private field and modify it in the way it wants. I do not understand what is the point of having encapsulation then . Can you please provide me some examples to understand encapsulation . Also scenarios where encapsulation was not used and problems which can occur because of that.
Upvotes: 1
Views: 209
Reputation: 718718
Consider this example:
public class Address {
private int doorNumber;
public int getDoorNumber() {
return doorNumber;
}
public void setDoorNumber(int doorNumber) {
if (doorNumber <= 0) {
throw new IllegalArgumentException("door number must be > 0");
}
this.doorNumber = doorNumber;
}
}
If the doorNumber
field was declared as public
, some code could violate the constraint that the door numbers in addresses should be positive numbers.
Consider this example:
public class Address {
private String doorNumber;
public int getDoorNumber() {
return Integer.parseInt(doorNumber);
}
public String getDoorNumber2() {
return doorNumber;
}
public void setDoorNumber(int doorNumber) {
this.doorNumber = doorNumber + "";
}
public void setDoorNumber(String doorNumber) {
this.doorNumber = doorNumber;
}
}
Note that we evolving our API so that we can represent the address "221B Baker St, London", but still allowing our old "house numbers are integers" API to be used ... (sort of).
But if doorNumber
had been public, then we would have been forced to change every place in the codebase where Address.doorNumber
had been used.
Upvotes: 1
Reputation: 298123
Look at the following counter-example:
class Address
{
int floor, door;
public int getDoorNumber()
{
return floor*100+door;
}
public void setDoorNumber(int doorNumber)
{
int newFloor=doorNumber/100;
if(newFloor<0 || newFloor>6)
throw new IllegalArgumentException("no such door "+doorNumber);
floor=newFloor;
door=doorNumber-newFloor*100;
}
}
The code calling setDoorNumber(10)
still works without needing any change. The independence of the property “doorNumber” from the object’s internal representation, plus the possibility to validate the input value, are the key point of encapsulation. You can’t do that with a field like public int doorNumber;
Besides that, there are developers considering a method like setDoorNumber(int)
being contradicting encapsulation, or at least, be a weak form of encapsulation. A stronger encapsulation model would work without such a public
setter method but providing high-level operations only. Such an operation, like booking a room in a hotel would perform much more related operations, involving other objects, and consistency checks before internally assigning a room number to an address…
Upvotes: 2
Reputation: 22224
Using getters and setters has some benefits over making fields public :
You can redesign the internals of your class by replacing int doorNumber;
with one or more fields of possibly different type. In such a case you can keep the getter and setter and that means other classes wouldn't have to be modified. If you had preferred private fields, any change in this class would enforce changes in any other class that uses it.
You can add validation and or reformatting logic inside a setter or getter, without changing the type of the field. Otherwise, if you used public fields, this logic would have to be repeated in any other class that accesses this field.
You can read more about it at Effective Java item 14
Upvotes: 1