Java bank - Abstract class

Extend RuntimeException to create an exception class.
We will use this when withdrawing more than the balance.

Custom Exception 1

Right-click on a space in the Eclipse editor view to display the context menu.
Select the "Source and Generate Constructors from SuperClass ..." to create constructors.

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);
  }
}

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

Change the Account class to an abstract class and 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 ..
}

Generate a standard 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 extend 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 ..  
}