Mastering Object-Oriented Programming in Java: A Comprehensive Guide with a Banking System Case Study
Object-oriented programming (OOP) is a fundamental concept in software development that allows developers to create reusable, maintainable, and scalable code. Java, a popular programming language, supports OOP principles, enabling developers to design and implement robust applications. In this response, we'll explore the key concepts of OOP in Java, including inheritance, polymorphism, encapsulation, and abstraction, and create a real-world case study of a simple banking system.
Inheritance
Inheritance is the process of creating a new class based on an existing class. The new class inherits the properties and methods of the existing class and can also add new properties and methods or override the ones inherited. In Java, inheritance is implemented using the extends keyword.
Example:
java
// Parent class
public class Animal {
private String name;
public Animal(String name) {
this.name = name;
}
public void sound() {
System.out.println("The animal makes a sound.");
}
}
// Child class
public class Dog extends Animal {
public Dog(String name) {
super(name);
}
@Override
public void sound() {
System.out.println("The dog barks.");
}
}
In this example, the Dog class inherits the properties and methods of the Animal class and overrides the sound() method to provide a specific implementation for dogs.
Polymorphism
Polymorphism is the ability of an object to take on multiple forms. In Java, polymorphism is achieved through method overriding or method overloading. Method overriding occurs when a subclass provides a specific implementation of a method that is already defined in its superclass. Method overloading occurs when multiple methods with the same name can be defined with different parameter lists.
Example:
java
// Parent class
public class Shape {
public void area() {
System.out.println("The area of the shape is unknown.");
}
}
// Child class
public class Circle extends Shape {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public void area() {
System.out.println("The area of the circle is " + Math.PI radius radius);
}
}
// Child class
public class Rectangle extends Shape {
private double width;
private double height;
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
@Override
public void area() {
System.out.println("The area of the rectangle is " + width height);
}
}
In this example, the Circle and Rectangle classes override the area() method to provide specific implementations for each shape.
Encapsulation
Encapsulation is the concept of hiding the implementation details of an object from the outside world and only exposing the necessary information through public methods. In Java, encapsulation is achieved by using private instance variables and public methods to access and modify those variables.
Example:
java
public class BankAccount {
private double balance;
public BankAccount(double initialBalance) {
balance = initialBalance;
}
public void deposit(double amount) {
balance += amount;
}
public void withdraw(double amount) {
if (amount <= balance) {
balance -= amount;
} else {
System.out.println("Insufficient funds.");
}
}
public double getBalance() {
return balance;
}
}
In this example, the BankAccount class encapsulates the balance variable and provides public methods to deposit, withdraw, and retrieve the balance.
Abstraction
Abstraction is the concept of showing only the necessary information to the outside world while hiding the implementation details. In Java, abstraction is achieved by using abstract classes or interfaces to define the interface of an object and hiding the implementation details.
Example:
java
public abstract class PaymentMethod {
public abstract void makePayment(double amount);
}
public class CreditCard extends PaymentMethod {
@Override
public void makePayment(double amount) {
System.out.println("Payment made using credit card for $" + amount);
}
}
public class PayPal extends PaymentMethod {
@Override
public void makePayment(double amount) {
System.out.println("Payment made using PayPal for $" + amount);
}
}
In this example, the PaymentMethod abstract class defines the makePayment() method, and the CreditCard and PayPal classes provide specific implementations of that method.
Case Study: Simple Banking System
Now, let's create a simple banking system using the OOP principles discussed above.
java
// Account class
public abstract class Account {
private String accountNumber;
private double balance;
public Account(String accountNumber, double initialBalance) {
this.accountNumber = accountNumber;
balance = initialBalance;
}
public void deposit(double amount) {
balance += amount;
}
public void withdraw(double amount) {
if (amount <= balance) {
balance -= amount;
} else {
System.out.println("Insufficient funds.");
}
}
public double getBalance() {
return balance;
}
}
// CheckingAccount class
public class CheckingAccount extends Account {
private double overdraftLimit;
public CheckingAccount(String accountNumber, double initialBalance, double overdraftLimit) {
super(accountNumber, initialBalance);
this.overdraftLimit = overdraftLimit;
}
@Override
public void withdraw(double amount) {
if (amount <= getBalance() + overdraftLimit) {
super.withdraw(amount);
} else {
System.out.println("Insufficient funds.");
}
}
}
// SavingsAccount class
public class SavingsAccount extends Account {
private double interestRate;
public SavingsAccount(String accountNumber, double initialBalance, double interestRate) {
super(accountNumber, initialBalance);
this.interestRate = interestRate;
}
public void addInterest() {
double interest = getBalance() interestRate / 100;
deposit(interest);
}
}
// Bank class
public class Bank {
private List<Account> accounts;
public Bank() {
accounts = new ArrayList<>();
}
public void addAccount(Account account) {
accounts.add(account);
}
public void printAccountBalances() {
for (Account account : accounts) {
System.out.println("Account Number: " + account.getClass().getSimpleName() + " Balance: $" + account.getBalance());
}
}
}
In this example, we define an abstract Account class with concrete subclasses CheckingAccount and SavingsAccount. The Bank class manages a list of accounts and provides methods to add accounts and print account balances.
java
public class Main {
public static void main(String[] args) {
Bank bank = new Bank();
CheckingAccount checkingAccount = new CheckingAccount("12345", 1000, 500);
SavingsAccount savingsAccount = new SavingsAccount("67890", 500, 5);
bank.addAccount(checkingAccount);
bank.addAccount(savingsAccount);
checkingAccount.deposit(500);
savingsAccount.addInterest();
bank.printAccountBalances();
}
}
In the main() method, we create a Bank object and add two accounts: a checking account and a savings account. We then deposit funds into the checking account and add interest to the savings account. Finally, we print the balances of all accounts in the bank.
This simple banking system demonstrates the use of OOP principles, including inheritance, polymorphism, encapsulation, and abstraction. The system is extensible, allowing us to add new types of accounts and banking operations while maintaining a modular and maintainable design.

Find Powerful AI Prompts
Discover, create, and customize prompts with different models, from ChatGPT to Gemini in seconds

Simple Yet Powerful
Start with an idea and use expert prompts to bring your vision to life!