Java bank - Abstract class

Modify the existing account class to an abstract class, and modify the normal account and the minus account to inherit the abstract account class. If you need a new kind of account class, then this class will inherit the abstract account class.

Let's create a custom exception class to use when there is insufficient amounts at the time of withdrawal.
Create and save InsufficientBalanceException class to inherit RuntimeException as shown below.
Custom Exception 1
Right-click on an empty space in the Eclipse editor view to display the context menu.
Select Source and Generate Constructors form SuperClass ... to create the constructor.
Custom Exception 2

InsufficientBalanceException.java
package net.java_school.bank;

public class InsufficientBalanceException extends RuntimeException {

  public InsufficientBalanceException() {
    super();
  }

  public InsufficientBalanceException(String message, Throwable cause) {
    super(message, cause);
  }

  public InsufficientBalanceException(String message) {
    super(message);
  }

  public InsufficientBalanceException(Throwable cause) {
    super(cause);
  }

}

Create an exception class to use when registering an account with an existing account number in the same way as above.

DuplicateAccountException.java
package net.java_school.bank;

public class DuplicateAccountException extends RuntimeException {

  public DuplicateAccountException() {
    super();
  }

  public DuplicateAccountException(String message, Throwable cause) {
    super(message, cause);
  }

  public DuplicateAccountException(String message) {
    super(message);
  }

  public DuplicateAccountException(Throwable cause) {
    super(cause);
  }

}

In the example, We use only constructors with string arguments. So, you can shorten it like this:

InsufficientBalanceException.java
package net.java_school.bank;

public class InsufficientBalanceException extends RuntimeException {

  public InsufficientBalanceException(String message) {
    super(message);
  }

}
DuplicateAccountException.java
package net.java_school.bank;

public class DuplicateAccountException extends RuntimeException {

  public DuplicateAccountException(String message) {
    super(message);
  }

}

Apply Abstract class to the example

By modifying the account class to an abstract class, you can create different kinds of account classes by inheriting the abstract account class.

Change the account class to an abstract class. Change the withdraw() to an abstract method.

Account.java
public abstract class Account {
  private String accountNo;
  private String name;
  protected double balance;
  protected List<Transaction> transactions = new ArrayList<Transaction>();
	
  static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy/MM/dd");
  static final SimpleDateFormat TIME_FORMAT = new SimpleDateFormat("HH:mm:ss");
  static final String DEPOSIT = "Deposit";
  static final String WITHDRAW = "Withdrawal";
  static final NumberFormat NUMBER_FORMAT = NumberFormat.getInstance();

  //.. Omitted ..
            
  public abstract void withdraw(double amount);

  //.. Omitted ..

  public abstract String getKind();

  //.. Omitted ..
    
}

If you need a new kind of account class, the new one will inherit the abstract account class.

Generate a regular account that does not allow a negative balance.

NormalAccount.java
package net.java_school.bank;

import java.util.Calendar;
import java.util.Date;

public class NormalAccount extends Account {
  static final String KIND = "Normal";

  public NormalAccount() {}
	
  public NormalAccount(String accountNo, String name) {
    super(accountNo, name);
  }

  public NormalAccount(String accountNo, String name, double balance) {
    super(accountNo, name, balance);
  }
	
  @Override
  public void withdraw(double amount)  {
    if (amount > balance) {
      throw new InsufficientBalanceException("There is not enough balance.");
    }
    balance = balance - amount;
    Transaction transaction = new Transaction();
    Calendar cal = Calendar.getInstance();
    Date date = cal.getTime();
    transaction.setTransactionDate(Account.DATE_FORMAT.format(date));
    transaction.setTransactionTime(Account.TIME_FORMAT.format(date));
    transaction.setAmount(amount);
    transaction.setBalance(balance);
    transaction.setKind(Account.WITHDRAW);
    transactions.add(transaction);
  }
	
  @Override
  public String getKind() {
    return KIND;
  }

}

Modify the minus account class to inherit the abstract account class.

MinusAccount.java
package net.java_school.bank;

import java.util.Calendar;
import java.util.Date;

public class MinusAccount extends Account {
  static final String KIND = "Minus";

  public MinusAccount() {}

  public MinusAccount(String accountNo, String name) {
    super(accountNo, name);
  }

  public MinusAccount(String accountNo, String name, double balance) {
    super(accountNo, name, balance);
  }
    
  @Override
  public void withdraw(double amount) {
    balance = balance - amount;
    Transaction transaction = new Transaction();
    Calendar cal = Calendar.getInstance();
    Date date = cal.getTime();
    transaction.setTransactionDate(Account.DATE_FORMAT.format(date));
    transaction.setTransactionTime(Account.TIME_FORMAT.format(date));
    transaction.setAmount(amount);
    transaction.setBalance(balance);
    transaction.setKind(Account.WITHDRAW);
    transactions.add(transaction);
  }

  @Override
  public String getKind() {
    return KIND;
  }
        
}

Modify the Bank class as below.

Bank.java
public class Bank {

  //.. Omitted ..  

  @Override
  public void addAccount(String accountNo, String name) {
    Account account = this.getAccount(accountNo);
    if (account != null) throw new DuplicateAccountException("Duplicated account.");
      accounts.add(new NormalAccount(accountNo, name));
    }

  @Override
  public void addAccount(String accountNo, String name, double balance) {
    Account account = this.getAccount(accountNo);
    if (account != null) throw new DuplicateAccountException("Duplicated account.");
    accounts.add(new NormalAccount(accountNo, name, balance));

  }

  public void addAccount(String accountNo, String name, String kind) {
    Account account = this.getAccount(accountNo);
    if (account != null) throw new DuplicateAccountException("Duplicated account.");
    if (kind != null && kind.equals("-")) {
      accounts.add(new MinusAccount(accountNo, name));
    } else {
      accounts.add(new NoramlAccount(accountNo, name));
    }
  }
    
  public void addAccount(String accountNo, String name, double balance, String kind) {
    Account account = this.getAccount(accountNo);
    if (account != null) throw new DuplicateAccountException("Duplicated account.");
    if (kind != null && kind.equals("-")) {
      accounts.add(new MinusAccount(accountNo, name, balance));
    } else {
      accounts.add(new NoramlAccount(accountNo, name, balance));
    }
  }
    
  //.. Omitted ..  

}