Real World Example

Bank Accounts

Banking systems share common account logic (number, balance, deposit) in a parent class, while each account type adds or changes rules: savings earn interest, current accounts allow an overdraft.

Example

public class Main {
    public static void main(String[] args) {
        SavingsAccount s = new SavingsAccount("SB-1001", 10000, 4.0);
        CurrentAccount c = new CurrentAccount("CA-2001", 5000, 10000);

        s.withdraw(12000);
        s.addYearlyInterest();
        c.withdraw(12000);

        System.out.println(s);
        System.out.println(c);
    }
}

class Account {
    protected final String number;
    protected double balance;

    Account(String number, double balance) {
        this.number = number;
        this.balance = balance;
    }

    boolean canWithdraw(double amount) {
        return amount <= balance;
    }

    final void withdraw(double amount) {     // subclasses customise canWithdraw, not this flow
        if (canWithdraw(amount)) {
            balance -= amount;
            System.out.println(number + ": withdrew " + amount);
        } else {
            System.out.println(number + ": insufficient funds for " + amount);
        }
    }

    @Override
    public String toString() {
        return getClass().getSimpleName() + " " + number + " balance=" + balance;
    }
}

class SavingsAccount extends Account {
    private final double ratePercent;

    SavingsAccount(String number, double balance, double ratePercent) {
        super(number, balance);
        this.ratePercent = ratePercent;
    }

    void addYearlyInterest() {
        balance += balance * ratePercent / 100;
    }
}

class CurrentAccount extends Account {
    private final double overdraftLimit;

    CurrentAccount(String number, double balance, double overdraftLimit) {
        super(number, balance);
        this.overdraftLimit = overdraftLimit;
    }

    @Override
    boolean canWithdraw(double amount) {
        return amount <= balance + overdraftLimit;
    }
}

Output

SB-1001: insufficient funds for 12000.0
CA-2001: withdrew 12000.0
SavingsAccount SB-1001 balance=10400.0
CurrentAccount CA-2001 balance=-7000.0

Practice

Exercise: Add a FixedDepositAccount that never allows withdrawal before maturity. Hint: override canWithdraw and use a boolean matured field.

Show answer
class FixedDepositAccount extends Account {
    private boolean matured;

    FixedDepositAccount(String number, double balance) {
        super(number, balance);
    }

    void mature() { matured = true; }

    @Override
    boolean canWithdraw(double amount) {
        return matured && super.canWithdraw(amount);
    }
}