In this segment, I will talk about designing classes and show the various differences between Object Oriented & Procedural Programming.
Abstracting & Encapsulating Classes
To make programming easier for programmers, classes are separated their implementation from how the classes are used or made to function. This is called Class abstraction.
The “fine-details” or “inner processes” of a class’s implementation are hidden from a user, because he does not need to know how the class is implemented. This is called Class encapsulation.
Let me give you an example that shows you how useful class encapsulation is. Let’s say that you made a circle object. Class encapsulation enables you to find the area of this circle object without knowing how the area is computed.
Another example is when you build a computer from parts you buy from online. You don’t need to know exactly how every single component works (class encapsulation). And you only need a general idea of what each part does so that you can put it together (class abstraction) i.e. motherboard connects everything, video card is responsible for the video, network card is responsible for connecting to the internet, cpu is the “brain” of the computer, etc.
So class abstraction is simplification of how a class is to be used. And class encapsulation is hiding the fine details of how a class works.
Loan Example
In this example we will be deconstructing loans to learn about class abstraction & encapsulation.
A loan can be seen as an object of the Loan class.
The data properties would consist of the interest rate, the amount loaned, the time period of the loan, etc.
The methods would be the process of computing the monthly and total payments for the loan.
So let’s say that you buy a car. A loan object is made from instantiating the Loan class. The Loan class is composed of the interest rate, the size of the loan, and the how long the loan lasts.
After that, you can use the methods to calculate the monthly and total payments for your loan. And you are not required to know the detail of how the methods works as a user of the Loan class.
Below I will be showing a program that calculates loan payments. Note that because the code for calculating the loan payments is in the main method, the program currently cannot reuse this code.
But defining the static methods for evaluating the monthly and total loan payments fixes the problem mentioned above.
But again, defining static methods is only a limited solution. It’s limitations show when you try to associate a date with the loan. Then you are forced to use objects to connect a date with a loan payment.
As you can see in Java, Object Oriented programming is focused on objects that are defined by actions and data inside the object. To contrast, Procedural programming is driven by actions which are separated from its data.
Loan Class Encapsulation via UML
So to tie together a date with a loan, you can make the loan class have the date and the loan’s properties in data fields. In this way, a loan object contains data and actions needed to process the data while at the same time integrating the loan data and actions into one object. With this in mind, here is how the UML diagram looks for the Loan class:

Notice that we don’t know or see the code of the actual Loan class. But we can use a UML diagram to symbolize what is in the Loan class. In this way, we are “Encapsulating” the Loan class for the user.
Testing the Encapsulated Loan Class
The Loan class UML diagram right above can be used in place of the actual Loan class code. The UML can be used in place of the Loan class code to develop a Java program that tests the Loan class, which you can see down below:
import java.util.Scanner;
public class TestLoanClass {
//Main Method
public static void main(String[] args) {
// Make a Scanner Object
Scanner input = new Scanner(System.in);
// Enter the yearly interest rate
System.out.print("Enter the yearly interest rate, for example, 8.25: ");
double yearlyInterestRate = input.nextDouble();
// Enter the number of years
System.out.print ("Enter the number of years as an integer: ");
int yearDuration = input.nextInt();
// Enter the loan amount
System.out.print("Enter the loan amount, for example, 120000.95: ");
double loanSize = input.nextDouble();
// Make the Loan object
Loan loan = new Loan(yearlyInterestRate, yearDuration, loanSize);
// Display loan date, monthly payment, and total payment
System.out.printf("The loan was made on %s\n" + "The monthly payment is %.2f\nThe total payment is %.2f\n", loan.fetchLoanTime().toString(), loan.fetchMonthlyPayment(), loan.fetchTotalPayment());
}
}
Output:

So you can see that the main method reads the interest rate, the duration of the payment, and the loan size. The main method also makes the Loan object, fetches the payment per month, and the total payment via the usage of the instance method in the Loan class.
Extra Notes:
printfallows you to format what you are printing out to the console.- The
%character automatically substitutes with a value. %.2fsyntax tells Java to return your variablewith 2 decimal places.2in decimal representation of a floating-point numberffrom the start of the format specifier%.- The use of
%swill result in thetoString()method being called on the object.
Now down below I will show you the code that makes up the Loan class.
Revealing the Loan Class (un-encapsulated)
Above, I showed a UML diagram that acted to “encapsulate” or hide the Loan Class. Even though you didn’t see in detail what the Loan Class is, you are still able to test the Loan Class by using the UML. Down below, I will show you the “details” that I’ve previously encapsulated from the Loan Class.
public class Loan {
private double yearlyInterestRate;
private int yearDuration;
private double loanSize;
private java.util.Date loanTime;
//The Default Constructor for the Loan Class
public Loan() {
this(2.5, 1, 1000);
}
// Construct a loan with a specified yearly interest rate, duration, and loan size
public Loan(double yearlyInterestRate, int yearDuration, double loanSize) {
this.yearlyInterestRate = yearlyInterestRate;
this.yearDuration = yearDuration;
this.loanSize = loanSize;
loanTime = new java.util.Date();
}
// Return the Yearly Interest Rate
public double fetchYearlyInterestRate() {
return yearlyInterestRate;
}
// Return the duration of the loan
public int fetchYearDuration() {
return yearDuration;
}
// Return the size of the loan
public double fetchLoanSize() {
return loanSize;
}
// Return the time when the loan was taken
public java.util.Date fetchLoanTime() {
return loanTime;
}
// Set a yearly interest rate
public void setYearlyInterestRate(double yearlyInterestRate) {
this.yearlyInterestRate = yearlyInterestRate;
}
// Set the loan duration
public void setYearDuration(int yearDuration) {
this.yearDuration = yearDuration;
}
// Set the size of the loan
public void setLoanSize(double loanSize) {
this.loanSize = loanSize;
}
// Find and Calculate the monthly payment to return
public double fetchMonthlyPayment() {
double monthlyInterestRate = yearlyInterestRate / 1200;
double monthlyPayment = loanSize * monthlyInterestRate / (1 - (1/ Math.pow(1 + monthlyInterestRate, yearDuration * 12)));
return monthlyPayment;
}
// Find and Calculate the total payment
public double fetchTotalPayment() {
double totalPayment = fetchMonthlyPayment() * yearDuration * 12;
return totalPayment;
}
}
So I want to drive home a few points through this exercise. First, Java programmers has to design their programs/classes to be encapsulated and abstract, so that their team members can quickly understand what the program/class does and build upon it, and so that clients can use the Java application without much knowledge about how the program/class works and instead given a simple explanation that they can understand quickly.
To show the usefulness of class encapsulation & abstraction, let’s take into consideration the output of the testClassLoan.java program. Imagine that the client or user only sees is what is in the console; none of the code. The console asks the user to input the yearly interest rate, the number of years the loan lasts, and the size of the loan- which is easily understood by the client/user. After executing the program the client receives information on the current time that the loan was made and what the monthly & total payments are- all without needing to know what made the program work.
Let me finish by saying that the purpose of abstraction & encapsulation is to improve the usability and flexibility of a class or program.
◄◄◄BACK | NEXT►►►
