Definition: Encapsulation and data hiding are the key features of object oriented programming. Encapsulation refers to the ability to package related behavior in an object bundle and control or restrict their access in both function and data from other objects. It necessarily is all about packaging related stuff together and keeping them away from external elements. You will note that keywords encapsulation along with data hiding is used interchangeably all over.
Information is encapsulated within a class and may be hidden from all or portions of the world outside the encapsulating class by using the appropriate access specifier. The access specifier controls who has access to which members of the class and access to the class itself. The ability to encapsulate and hide information enables us to guarantee the integrity of data as well as to make changes in the implementation details of members without returning any changes in the programs from which these details were hidden, and the public getter and setter methods are set with private fields, enabling data to set and gotten from them.
We’ll be covering the following topics in this tutorial:
Encapsulation Explanation
Encapsulation binds fields and its associated methods into a single unit. It is achieved using concept of class. When you assign a class in object-oriented programming, it is said that the first principle you should consider is encapsulation. Group the associated data and its behavior in a bucket. The main benefit of encapsulation is maintainability. Believe it all or not, that’s pretty much it when it comes to encapsulation! You can leave it as simple as that with nothing more or less.
Many computer languages which came earlier, like FORTRAN, BASIC, Pascal, C, etc. handled data in an ‘open’ manner. Every component (like subroutines, functions) in the program written in those languages can access data defined for the whole program. This feature, though advantageous in many occasions, has some disadvantages in a few cases. When a data is declared for all components of a program, any element in that program can alter the data. However, in most real-life problems information is to be protected from modification by all excepting by the specified components.
Not only data but also the procedures that manipulate the data are to be guarded against misuse by other components of a program. Each method defined for a specific task is allowed to be accessed only by a particular component or by all other elements of a program in varying degrees. This mechanism of protecting data and methods of a program is called encapsulation.
In the Java language, encapsulation is realized through a description concept called class. A Java class contains variables representing data and methods that manipulate the data. The methods describe the way in which the data is managed. The variables and methods of a class are called members of the class. The members of a class can be declared as private or public.
A class itself cannot be used as such. Realistic entities, called objects, are to be created as per the description of the class like buildings are constructed using blueprint. One or more objects constitute a Java program.
Public data and methods can be accessed by other objects of a program. The private data and methods can be located only within the same object. This mechanism protects private members. The only way to access a private member by an external object is through the public method, which is well defined (by the user). Thus public methods encapsulate the data and methods of one object and act as an interface to other objects. The public method provides a channel for communication with external objects.
Java encapsulation access specifiers
Take the Java encapsulation outline example below. you are essentially following the principles of encapsulation.
In Java, we have three access specifiers:public, private and protected, that can be used with the class members.
Access Specifiers | Purpose |
Public | Members declared public are accessible anywhere the class is accessible. This is the most commonly used access specifier for methods. |
Private | Members declared private are accessible only from methods inside the class and not from outside the class. This is the most commonly used specifier for fields. |
Protected | Members declared protected are accessible from methods in any class in the same package and from any subclass anywhere. |
If no access specifier is used, Java assigns a default package access to the members. Members with default access are accessible from methods in any class in the same package.
The syntax for specifying access specifiers with the members of the class and the class itself is as follows.
For Field: [accessspecifier] type fieldname [=expression] ;
For Methods: [accessspecifier] returnType methodname ([ParameterList}) { … }
For class: [accessspecifier] class className {…. }
For constructor: [accessspecifier] ConstructorName ( [parameterList] ) {… }
All the access specifier can be used with fields, methods and constructors but the class can only have public access specifier.
We shall now discuss the public and private access specifiers here. In order to understand the use of access specifiers, let us consider the following program.
class Rectangle {
public int length;//public access
public int breath;//public access
static int rectCount =0;// default access
//Constructor to initialize length and breath
Rectangle(){ rectCount++;}//method to calculate area of rectangle
public int area(){int rectArea; rectArea = length * breath;return rectArea;}
}
public class AccessSpecifier {
public static void main(String[] args){//create first rectangle object
Rectangle firstRect =new Rectangle();
//accessing public members outside the Rectangle class
firstRect.length =-10;
firstRect.breath =-20;
System.out.println(“Area of rectangle is = “+firstRect.area());
//Rectangle.rectCount = 5;//accessing member with default access
System.out.println(“Number of object created = “+Rectangle.rectCount);
}
}
Explanation: In the class Rectangle, the length and breadth fields are specified as public. The class variable rectCount has no access specifier specified so it has a default access. The method area () also has public access. All the public fields and methods are accessible from outside the class. In the above program, we can access all these members in the AccessSpecifier class. Also, the class variable rectCount with default access is accessible from the outside class as shown in the program.
In this program, the fields length and breadth and rectCount can be modified directly but this is not a good practise for two reasons.
(a) The data may be tempered. For example: The field rectCount can be set to any arbitrary value using the statement,
Rectangle.rectCount 5;
This tampering will not display the correct number of objects created.
(b) It makes the class difficult to maintain and vulnerable to bugs. For example : Suppose you want to modify the Rectangle class to ensure that the length and breadth fields should be positive after other programs have already used the class. In such a situation,
you will have to make changes not only in the Rectangle class but also in the programs that uses the Rectangle class. This is because the programs may have modified the length and breadth fields directly. For example :
firstRect.length = -10;
To prevent direct modification of the fields, it is recommended to declare the fields private using the private access specifier. This is known as data field encapsulation.
Whenever a field is declared private it cannot be accessed by an object reference outside the class. So if length and breadth are declared private, then the following statements are invalid,
firstRect.length = 10; //Invalid
firstRect.breadth 20; //Invalid
However, if you want to retrieve and modify a private field then you have to provide a get () method to retrieve the value of the field and set () method to set the new value of the field. The previous program on modification will now look like.
Output: Area of rectangle is = 200
Number of object created = 1
//use of public and default access specifer
class Rectangle {
public int length;//public access
public int breath;//public access
static int rectCount =0;// default access
//Constructor to initialize length and breath
Rectangle(int l,int b){
length =(l>=0)?l:0;
breath =(b>=0)?b:0;
rectCount++;
}
static int count()//return number of objects
{return rectCount;}
int getLength()//return length
{return length;}
int getBreath()//return breath
{return breath;}
//method to calculate area of rectangle
public int area(){int rectArea; rectArea = length * breath;return rectArea;}
}
public class PrivateTest {
public static void main(String[] args) {//create first rectangle object
Rectangle firstRect =new Rectangle(2,3);
System.out.println(“Length = “+firstRect.getLength());
System.out.println(“Breath = “+firstRect.getBreath());
System.out.println(“Area of rectangle is = “+firstRect.area());
System.out.println(“Number of object created = “+Rectangle.rectCount);
}
}
Output: Length= 2
Breadth= 3
Area of rectangle is 6
Number of object created 1
Explanation: The following figure shows which fields and methods of Rectangleclass are accessible by the PrivateTest class.
Why we need Encapsulation in Java?
Encapsulation is essential in Java because:
• To prevent direct modification of the fields.
• It binding object state(fields) and behaviour (methods) together.
• Modifies the code who has access to which members of the class and access to the class itself.
• Helps us to achieve a cohesion.
• Helps us to achieve simplicity and uniformity for the development of distributed applications.
• They are supposed to help creating software that is more reusable and more scalable.
• It helps to hide internal details of your class from outside.
• It provides the security and flexibility. Even if the binding the data(instance variables) is changed from end user.
• Helps us in hiding the data of a class from an illegal direct access.
• Helps us to make a flexible code which is easy to change and maintain.
• helpful in achieving low coupling.
• Class fields may be read or write only.
• A class has complete control over what data stored in the fields.
• No class user know how the data stored. Classes can modify field data types, and class users not need to modify any code.
• The most significant benefit with encapsulation is that it provides us with that ability to modify code we implemented without breaking the code used by other users. It ensures that our code is extensible, maintainable and flexible and ensures that unit testing is straightforward. We can also modify parts of our code without having any effect on the rest.
• We achieve encapsulation by using a class to keep the data and related methods together in one unit.
• It is a technique for protecting information in one object from other objects.
• It gives us access control to control what can be accessed and by what; those controls may be public, private and protected.
Now, let’s illustrate why we want to encapsulate knowledge in programs.
In the above example, The Class book contains two instance variables which has two data members ISBN and name. So any Classes in the same package can also access values of those variables by creating the object of book class. Thus, we don’t have control over the values of the variables. In order to solve this problem, we encapsulate the book class.
Benefits of Encapsulation
• Data Hiding: Information is encapsulated within a class and may be hidden from all or portions of the world outside the encapsulating class by using the appropriate access specifier. The access specifier controls who has access to which members of the class and access to the class itself. The ability to encapsulate and hide information enables us to guarantee the integrity of data as well as to make changes in the implementation details of members without returning’any changes in the programs from which these details were hidden .
• Increased Flexibility: It also adds enomorous flexibility to the way in which you can program your application.
• Reusability: The main advantage of encapsulation is the reusability of the code. Encapsulation allows well tested code to be reused and enable changes to be made once and have effect in all relevant places.
Abstraction vs. Encapsulation
There are several differences between the two:
• Java problems solved at the design level with abstraction and implementation level with encapsulation.
• We use abstraction for hiding unnecessary data and showing only the functionality; with encapsulation, the code and the data are hidden in one unit to protect external access.
• With abstraction, we can focus on what an object does and not how it did; with encapsulation, we are hiding the internal mechanics of how the object does what it does.
Real-World Example
We can demonstrate the difference between abstraction and encapsulation by using a real-world example. Let’s assume that you have got a mobile phone and you can use the buttons on the keypad to dial a specific number. You do not need to know how all this works, just that it does. In Java, this is an abstraction. Now, let’s say that you want to know how the mobile phone works internally? How do the keypad buttons connect to internal circuits to make them work? In Java, this would all be rolled into one unit and is called encapsulation.