Logout

Encapsulation and the Reasons for it

Refresher about OOP:

Object Oriented Programming (OOP) is an approach to programming which is different from the procedural approach which preceeded it. And though the "object" part of OOP is significant, there are other approaches which came about at the same time, and are grouped with OOP. Generally there are three big things which are thought of as being part of OOP:

The OOP "Big Three" In A Nutshell:

Basically, encapsulation is the strategy of protecting the way that data is manipulated by making attributes accessible only within the classes they have been defined, and allowing only the public interface of method headers able to be accessed by other classes.

Polymorphism is basically having the same method (same method name) work differently depending on what parameters are sent to it.

And inheritance is the ability of classes to inherit methods from other classes, without having to re-implement them.

 

Encapsulation

Every time we have made a "template" class, we have been been practicing encapsulation. To encapsulate means to surround or protect from things outside of the encapsulation. So what allows encapsulation in our template classes is the private modifier. By declaring a variable private, we prevent other classes from directly accessing and changing the variable. The variable will only be able to be affected by other classes via public methods which work with the variable. And the implementation of those methods can also be thought of as being encapsulated, since other classes can't see beyond the header.

Encapsulated Against What?

The reasons that we don't want attributes to be altered from other classes are many. One reason is to protect security in the conventional sense; i.e. to protect money and information from being altered/accessed inappropriately. For example, if a class keeps track of the amount of money you have in the bank, the bank wouldn't want you to be able to hack into the data regarding your balance, as you could make this any value you wish. And though encapsultaion does help security in this sense, it is used more generally to make programs more secure as in the stability sense. Encapsulation helps programs maintain the integrity of how their attributes are supposed to be handled.

Ultimately it is the programmer him/herself of particular code who knows best how the attributes in that code could/should be worked with. They know intimitely the sorts of things that need to be avoided so that the data is not corrupted, compromised or rended either problematic or useless. Compare this to the situation where the data in one class can be altered anyway another class chooses. We can assume that the programmers within a certain company or organization are not trying to sabotage each other's classes/programs, but it is much easier for them make mistakes when allowed to directly use the attributes of other colleague's code. There are just too many exceptional cases which need to be considered, and the author him/herself of each individual piece of code is best placed to handle these.

One similar problematic situation of un-encapsulated code is the sharing of libraries of data. For example, dlls, or dynamically linked libraries are collections of code which can be accessed by many different applications. So Microsoft Word, and Microsoft Excel may share a certain dll library which works with fonts. If one of these applications alters the data there, one would expect that it would be in a safe way, given that both of those applications were made by the same large company. But what if another application access and changes the data in one of those libraires, and it does it in a way that either Word or Excel do not like. Then we would have a problem. So in the same way, direct, un-managed sharing of attributes between classes is not a good idea.

So you are encouraged Always to make your attribute private, and have their manipulation occur only "behind closed doors", within the methods.


Encapsulation Example

In the following example, all the attributes are private, so none of them can be accessed directly. The only way we can access them is through the get methods, and the only way we can change them is through either the constructors or the set methods.

The best place to look in this example is the makeAPurchase() method for the idea of how things could be imporperly altered. Note that if the user is a staff member they get to purchase the food for 0.80 of the price. That 0.8 should not be able to be altered outside of this class, and it can't be since it's "behind the scenes" within the code of the method. And furthermore, the cardBalance of the user simply cannot be changed unless the setCardBalance method is used. So when this class is used, staff will get the 20% discount, as intended, and no other program will be able to change the card balance beyond using the methods where the user deposits money, or buys stuff.

(With this example, just do keep in mind that we would need to have a much more sophisticated, fully-functional, multi-class project to see more real examples of how data needs to be protected from mis-use.)

 5 public class LunchCard {
 6     private String userName = "not set yet";
 7     private double cardBalance = -999;
 8     private boolean isStaff = false;
 9 
10     public LunchCard(){
11 
12     }
13     public LunchCard(String userName, int cardBalance, boolean isStaff){
14         this.userName = userName;
15         this.cardBalance = cardBalance;
16         this.isStaff = isStaff;
17     }
44 
45     public double getCardBalance(){
46         return cardBalance;
47     }
48 
49     public boolean getIsStaff(){
50         return isStaff;
51     }
52 
53     public void setUserName(String userName){
54         this.userName = userName;
55     }
56 
57     public void setCardBalance(double cardBalance){
58         this.cardBalance = cardBalance;
59     }
60 
61     public void setIsStaff(boolean isStaff){
62         this.isStaff = isStaff;
63     }
64 
65     public void makeADeposit(double depositedAmount){
66         cardBalance += depositedAmount;
67     }
68 
69     public void makeAPurchase(double purchaseAmount){
70         if(isStaff){
71             purchaseAmount = 0.8 * purchaseAmount;
72         }
73         cardBalance -= purchaseAmount;
74     }
75 
76 }