Chapter 3 |
Encapsulation
Encapsulation - hiding the implementation details from the clients for security reasons.
Encapsulating instance fields, we declare them to be private by writing keyword
private
at the start of the declaration of each field, e.g.
// encapsulated instance fields private String breed; private int age;
Private fields are visible inside the class Dog (inside the Dog.java file), but not anywhere else. This means that we can no longer directly refer to private instance fields from the client class or any other classes.
To preserve the functionality of the client class, we need to provide public methods for the client class to access values of instance fields: the accessor methods (getters) and the mutator methods (setters).
If the value of an instance field has to be used outside its class (externally), it is common to write a public accessor method into the object class. Such method returns the value into the class where the value is needed. Here are accessors that provide access to the dog's breed and age fields:
// a public accessor method that returns the breed of the dog whose instance called the method public String getBreed() { return breed; } // a public accessor method that returns the age of the dog whose instance called the method public int getAge() { return age; }
The client class that wishes to print a dog's breed and age values must be changed to the following:
// This code works with our encapsulated Dogs System.out.println("Lisa is a " + liza.getBreed() + ". She is " + liza.getAge() + " years old."); // This code does not work with our encapsulated Dogs System.out.println("Lisa is a " + liza.breed + ". She is " + liza.age + " years old.");
It probably seems odd to use encapsulations and accessors. However, the accessor methods only return a copy of the field values (like breed and age) to the client class, but do not give the client any chance to change it. In other words, these accessor methods give the client class the read only access to the state of an object.
Another benefit of encapsulation is that later we can change the internal structure of our object without having to modify our client code.
On the other hand, when the Dog class is encapsulated, one drawback is that it is no longer easy for the client class to set state values for an object. This can be solved creating mutator methods in the object class:
// Set the breed of the dog whose instance called the method public void setProperties(String breed) { this.breed = breed; }
Note, it is absolutely legal to call object instance methods from its constructor or its other instance methods.
// Constructor public Dog(String name, String breed, int age, String size, String color) { setProperties(breed); this.age = age; this.name = name; this.size = "small"; this.color = color; }
Last but not least, we can also generate getters and setters in a fast way using IntelliJ: from the Code menu choose Generate.
Self-assessment
Chapter 3 |