Encapsulation refers to the bundling of data with the methods that
operate on that data. Often that definition is misconstrued
to mean that the data is somehow hidden.
In Java, you can have encapsulated data that is not hidden at all.
The language facility that bundles data with the operations that perform on that data is encapsulation. Note that encapsulation guarantees neither data protection nor information hiding. Nor does encapsulation ensure a cohesive class design. To achieve those quality design attributes requires techniques beyond the encapsulation provided by the language. As currently implemented, class
In Java, encapsulation is implemented by hiding details using the accessibility modifiers (i.e. public, protected, private, etc.). With these levels of accessibility you control the level of information hiding. The less restrictive the level, the more expensive change is when it happens and the more coupled the class is with other dependent classes (i.e. user classes, subclasses).
Think, for example, in the level of abstraction in the concept of a car. A car is complex in its internal implementation. They have several subsystem, like a transmission system, a break system, a fuel system, etc.
However, we have simplified its abstraction, and we interact with all cars in the world through the public interface of their abstraction. We know that all cars have a steering wheel through which we control direction, they have a pedal that when you press it you accelerate the car and control speed, and another that when you press it you make it stop, and you have a gear stick that let you control if you go forward of backward. These features constitute the public interface of the car abstraction. In the morning you can drive a sedan and then get out of it and drive an SUV in the afternoon as if it was the same thing.
It is not that you cannot open the hood and see how it all works. However, few of us know the details of how all these underlying features are implemented under the hood, and the truth is that we do not need to know the details to drive a car. All these things are encapsulated under the car abstraction. We only need to know the public interface of the abstraction.
Think of the time when cars did not have a hydraulics directional system. One day, the car manufactures invented it, and they decide it to put it in cars from there on. Still, this did not change the way in which users where interacting with them. At most, users experienced an improvement in the use of the directional system. A change like this was possible because the internal implementation of a car was encapsulated.
This clearly demonstrates that by hiding the details of how the directional systems was implemented, they could safely change it without affecting the public interface of the car and, correspondingly, without affecting the way users interacted with it.
Now, think that car manufactures decided to put the fuel cap below the car, and not in one of its sides. You go and buy one of these new cars, and when you run out of gas you go to the gas station, and you do not find the fuel cap. Suddenly you realize is below the car, but you cannot reach it with the gas pump hose. Now, we have broken the public interface contract, and therefore, the entire world breaks, it falls apart because things are not working the way it was expected. A change like this would cost millions. We would need to change all gas pumps in the world. When we break encapsulation we have to pay a price.
So, as you can see, the goal of encapsulation is to minimize interdependence and facilitate change. You maximize encapsulation by minimizing the exposure of implementation details. The state of a class should only be accessed through its public interface.
The beauty of encapsulation is the power of changing things without affecting its users.
Encapsulation:
Encapsulation is nothing but protecting anything which is prone to change. rational behind encapsulation is that if any functionality which is well encapsulated in code i.e maintained in just one place and not scattered around code is easy to change.
Suppose we have a class Loan has a constructor and than in various classes you have created instance of loan by using this constructor. now requirements change and you need to include age of borrower as well while taking loan. Since this code is not well encapsulated i.e. not confined in one place you need to change everywhere you are calling this constructor i.e. for one change you need to modify several file instead of just one file which is more error prone and tedious.Wouldn't it be better if you only need to make change at one place ? Yes that is possible if we encapsulate Loan creation logic in one method say createLoan() and client code call this method and this method internally crate Loan object. in this case you only need to modify this method instead of all client code.
// create loan can encapsulate loan creation logic
}
The language facility that bundles data with the operations that perform on that data is encapsulation. Note that encapsulation guarantees neither data protection nor information hiding. Nor does encapsulation ensure a cohesive class design. To achieve those quality design attributes requires techniques beyond the encapsulation provided by the language. As currently implemented, class
Position
doesn't contain superfluous or nonrelated data and methods, but Position
does expose both latitude
and longitude
in raw form. That allows any client of class Position
to directly change either internal data item without any intervention by Position
. Clearly, encapsulation is not enough. In Java, encapsulation is implemented by hiding details using the accessibility modifiers (i.e. public, protected, private, etc.). With these levels of accessibility you control the level of information hiding. The less restrictive the level, the more expensive change is when it happens and the more coupled the class is with other dependent classes (i.e. user classes, subclasses).
The Role of Abstraction
That's why, in my opinion, to really understand encapsulation, one must first understand abstraction.Think, for example, in the level of abstraction in the concept of a car. A car is complex in its internal implementation. They have several subsystem, like a transmission system, a break system, a fuel system, etc.
However, we have simplified its abstraction, and we interact with all cars in the world through the public interface of their abstraction. We know that all cars have a steering wheel through which we control direction, they have a pedal that when you press it you accelerate the car and control speed, and another that when you press it you make it stop, and you have a gear stick that let you control if you go forward of backward. These features constitute the public interface of the car abstraction. In the morning you can drive a sedan and then get out of it and drive an SUV in the afternoon as if it was the same thing.
It is not that you cannot open the hood and see how it all works. However, few of us know the details of how all these underlying features are implemented under the hood, and the truth is that we do not need to know the details to drive a car. All these things are encapsulated under the car abstraction. We only need to know the public interface of the abstraction.
Think of the time when cars did not have a hydraulics directional system. One day, the car manufactures invented it, and they decide it to put it in cars from there on. Still, this did not change the way in which users where interacting with them. At most, users experienced an improvement in the use of the directional system. A change like this was possible because the internal implementation of a car was encapsulated.
This clearly demonstrates that by hiding the details of how the directional systems was implemented, they could safely change it without affecting the public interface of the car and, correspondingly, without affecting the way users interacted with it.
Now, think that car manufactures decided to put the fuel cap below the car, and not in one of its sides. You go and buy one of these new cars, and when you run out of gas you go to the gas station, and you do not find the fuel cap. Suddenly you realize is below the car, but you cannot reach it with the gas pump hose. Now, we have broken the public interface contract, and therefore, the entire world breaks, it falls apart because things are not working the way it was expected. A change like this would cost millions. We would need to change all gas pumps in the world. When we break encapsulation we have to pay a price.
So, as you can see, the goal of encapsulation is to minimize interdependence and facilitate change. You maximize encapsulation by minimizing the exposure of implementation details. The state of a class should only be accessed through its public interface.
The beauty of encapsulation is the power of changing things without affecting its users.
Encapsulation:
Encapsulation is nothing but protecting anything which is prone to change. rational behind encapsulation is that if any functionality which is well encapsulated in code i.e maintained in just one place and not scattered around code is easy to change.
Suppose we have a class Loan has a constructor and than in various classes you have created instance of loan by using this constructor. now requirements change and you need to include age of borrower as well while taking loan. Since this code is not well encapsulated i.e. not confined in one place you need to change everywhere you are calling this constructor i.e. for one change you need to modify several file instead of just one file which is more error prone and tedious.Wouldn't it be better if you only need to make change at one place ? Yes that is possible if we encapsulate Loan creation logic in one method say createLoan() and client code call this method and this method internally crate Loan object. in this case you only need to modify this method instead of all client code.
Example of Encapsulation in Java
class Loan{
private int duration; //private variables examples of encapsulation
private String loan;
private String borrower;
private String salary;
private int duration; //private variables examples of encapsulation
private String loan;
private String borrower;
private String salary;
//public constructor can break encapsulation instead use
factory method
private Loan(int duration, String loan, String borrower, String salary){
this.duration = duration;
this.loan = loan;
this.borrower = borrower;
this.salary = salary;
}
private Loan(int duration, String loan, String borrower, String salary){
this.duration = duration;
this.loan = loan;
this.borrower = borrower;
this.salary = salary;
}
//no argument consustructor omitted here
// create loan can encapsulate loan creation logic
public Loan createLoan(String
loanType){
//processing based on loan type and than returning loan object
//processing based on loan type and than returning loan object
return loan;
}
}
In this same
example of Encapsulation in Java you
see all member variables are made private so they are well encapsulated you can
only change or access this variable directly inside this class. if you want to
allow outside world to access these variables is better creating a getter and
setter e.g. getLoan() that allows you to do any kind of validation, security
check before return loan so it gives you complete control of whatever you want
to do and single channel of access for client which is controlled and managed.