Session 3 |
Encapsulation
Encapsulation - hiding the implementation details (instance states) of an object from the clients of the object for security reasons.
To encapsulate instance fields of an object, we declare them to be private by writing the 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 methods for client class to access instance field values: 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 an 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:
// Returns the breed of the dog whose instance called the method public String getBreed(){ return breed; } // 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 " + liza.getBreed() + ". She is " + liza.getAge() + " years old."); // This code does not work with our encapsulated Dogs System.out.println("Lisa is " + 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 does 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 the 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 property values to an instance. This can be done creating mutator methods in the object class:
// Sets the breed of the dog whose instance called the method public void setProperties(String breed) { this.breed = breed; }
Note, it is absolutely legal for an object to call its own instance methods from its constructor or 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: in the Code menu choose Generate.
Self-assessment
Session 3 |