Java for Humans {Encapsulation & Access Modifiers}

View Table of Contents | Download Supporting Code | Subscribe to ModernNerd Youtube Channel for Coding Videos | By Lincoln W Daniel

As humans, we make use of the tools provided to us by companies, our parents, teachers, friends, and government. Most times, we don’t care about how the tools work behind the scenes; all we care about is that they work and get the job done when we call on them.

When you go to a vending machine and pay for cookies with a dollar bill, you don’t necessarily care how the machine knows you gave it a valid dollar instead of a piece of printer paper, but you do expect it to accept your dollar as a form of payment and for it to dispense your cookie. If the cookie only cost $0.75, you expect the machine to also give you a quarter back and you don’t care how it manages to do that. You are unaware of the amount of money the machine has in it and how it does the math to decide how much money to give back to you. With that, we can say that all of its functions are encapsulated.

The English dictionary defines “encapsulate” as so:

to enclose (something) in or as if in a capsule.

In computer science, we define encapsulation as such:

to provide an interface for (a piece of software or hardware) to allow or simplify access for the user.

Thus, encapsulation in Java and many OOP languages is the process of wrapping information and functionality in a class and providing methods of accessing them in order to provide a simple interface for users to access the information and make use of the functionality of the class.

Why Encapsulation is Important & Useful

Encapsulation is the reason you don’t have to calculate your own change when you go to a vending machine. You slip in your cash and out comes correct change. Behind the scenes, the machine is keeping track of how much money it has available, how much each item costs, and how much money you give it. It also has functions to dispense the right item if you provide it enough money as well as a function to calculate how much change to give you. This allows you to simply walk up, give it a dollar, select an item, get the item and your change, and go enjoy life without worrying about the complex calculations going on behind the scenes. This is why encapsulation is so great in programming.

In Java, we can use encapsulation to hide the hard work from the user of our program, or teammates who use our code, while providing them access to the functionality they need. Let’s model our vending machine situation in code to get a closer look of how awesome encapsulation is:

/*some methods have been omitted in this code snippet*/
public class VendingMachine {
private double cookieCost;
private double gumCost;
private double changeFromLastPurchase = 0;

public VendingMachine (double cookieCost, double gumCost) {
this.cookieCost = cookieCost;
this.gumCost = gumCost;
}

public double getCookieCost(){ return cookieCost; }
public double getGumCost(){ return gumCost; }

public void buyItem(String whichItem, double payment){
resetLastPurchaseChange();
if(itemExists(whichItem)) {
if(paymentIsEnough(whichItem, payment)) {
dispenseItem(whichItem);
calculateChange(whichItem, payment);
} else { alertUser(whichItem, payment); }
}
}

public double getChange() {
return changeFromLastPurchase;
}

private boolean paymentIsEnough(String whichItem, double payment) {
if(whichItem.equals("cookie")) {
return payment >= cookieCost;
} else if (whichItem.equals("gum")) {
return payment >= gumCost;
} else { return false; }
}

private void dispenseItem(String whichItem) {
System.out.println("Here's your " + whichItem);
}
    ...
}

Now, there’s a good deal of code there, so let’s break it down.

Access Modifiers

Encapsulation in Java would not be as effective as it is today without access modifiers. Access modifiers allow us to decide how parts of our classes can be accessed by other classes in other parts of our program.

If we want a field or method to be accessible from anywhere, by any class, we can mark it as public. By default fields, method, and classes are public to all other classes in their package. If we only want a field or method in our class to be accessed from within our class, we can mark them private. Finally, if we want to explicitly constrain the access of a field or method to subclasses of their class or other classes the same package, we can mark them as protected. Nonetheless, as a beginner, your focus is on public and private until you begin building larger programs.

In Java, by default fields, method, and classes are package-private, which means they cannot be accessed from outside of their package. That is only the case when we do not specify an access modifier. In this book, we only focus on public, private, and protected but it would be good to know this and research it more.
Classes can also be marked with access modifiers. At the top-level, scope one, a class can only be public or pack-private. An inner class, however, can be marked the same way as fields and methods, but that, too, is beyond the scope of this book. For our purposes, all of our classes will be marked as public.

Encapsulation & Our Vending Machine

Before we analyze our vending machine class, it’s important that you know there are a few methods missing from the snippet above. You can view the full class and the accompanying executable program in the supporting code section.

If we start at the top of our vending machine class, you’ll see that all three of its fields, cookieCost, gumCost, and changeFromLastPurchase, are private. This ensures that no outsiders can change their values because the owner of the machine wouldn’t want customers changing the prices of the items in the machine and choosing how much change customers get.

When creating an instance of the VendingMachine class, the owner must provide the cost of the items as arguments to the constructor. The only public methods are the constructor for the owner to construct a new instance of the vending machine, and the three functions users of the machine would care to use: getting the price of items, buying items, and getting their change.

When a customer walks up to an instance of our VendingMachine class, they can only call the three public methods because the rest, including the omitted ones, are private. The customer can ask to see how much a cookie or a gum is, and if they are satisfied with the prices our machine returns, they can invoke the machine’s buyItem() method to try to buy an item. Behind the scenes, our buyItem() method will call our other methods which are private to do the work.

public class StoreProgram {
public static void main(String[] args) {
System.out.println("Starting Store Program");

System.out.println("Owner creates vending machine.");
VendingMachine vendingMachine = new VendingMachine(0.75, 0.50);

System.out.println("Customer starts using machine.");
double costOfCookie = vendingMachine.getCookieCost();

System.out.println("Wow cookies cost " + costOfCookie);
System.out.println("and gum costs " + costOfGum);

System.out.println("I'm going to buy a cookie!");
vendingMachine.buyItem("cookie", 1.00);

double change = vendingMachine.getChange();
System.out.println("\nGot my change of " + change + " cents");
}
}

The buyItem() method will have to call our private itemExists() instance method to check if the item the user wants to buy actually exists in our machine. Next, if the item exists, the machine will call its private paymentIsEnough() instance method to check if the user paid enough money for the item. If the user paid enough for the item, the machine will call its private dispenseItem() instance method to give the user the item he/she just bought. Finally, the machine will call its private calculateChange() instance method for the purchase and store the result in the changeFromLastPurchase instance field. Finally, the user can call the machine’s public getChange() instance method to get his/her change from the last purchase. That’s it.

We have built a vending machine interface for our users to use with ease by employing encapsulation. You will want to make extensive use of encapsulation as you grow in your programming knowledge. It will make your code clearer and safer for you and teammates and easier for users.


One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.