Getting further and further behind in my class, I've got a project due that I can't seem to make click in my head. To top it off, the first part of it we haven't gotten back yet, so I don't even know if I'm on the right track.
For the first part, we were supposed to set up a Bank class to manage a number of Accounts. The bank class would create an account, close an account, and manage the operations of the account. I did most of that fairly well(I thought). The accounts would consist of the account number, account holder, and balance.

Now we need to add upon that:
Three types of accounts: Savings, Checking, and Loan
The three are similar:
in addition to previous info, accounts will keep a repository of the transactions they receive.
Savings Accounts will also have an annual interest that is paid to the account
Checking will also cash checks, which requires a check number, have an overdraft protection amount(balance and overdraft cannot be less than zero)
Loan will also have annual interest rate that is added to the balance, payments made to the loan.

Provide a bank controller: Opens and closes the bank. On opening the bank, the controller checks to see if the bank's state exists in a file. If the info exists, restore the bank's state to resume where the previous session ended. On closing the bank, save the bank's state to a file.
The bank will read a set of new transactions(as input) from a file and issue the transactions to the bank. At a minumum, the following:
Open the bank
Create an account
Close an account
Deposit to an account
Withdraw from an account
Cash a check
Apply monthly interest to Savings
Charge monthly int to loans
Close the bank

Rules:
Log all transactions on receipt
Balance >= 0 unless covered by overdraft
May be many accounts open at a time. Class should impose no limits on the number of accounts
Methods may be called in any order
Methods cannot work on a nonexistent account, if tried, throws an InvalidAccountException

We were just learning System.out.println("Welcome to Java!") a few short weeks ago. Since then it's been a non stop barrage of new info. I'm drowning here.
Here's what I've attempted so far:

Java Code:
import java.util.ArrayList;

public class Bank {
	private static ArrayList<Account> accountsList = new ArrayList<Account>();
	private static int numberOfAccounts = 0;
	private double balance;
	
	public Bank(ArrayList<Account> accountsList) {
		
	}
	
	public void add(Account account) {
		accountsList.add(account);
		numberOfAccounts++;
	}
	
	public static String createAccount() {
		String accountNumber = "";
		do {
			int accountNumInt = (int)(Math.random() * 1000000000);
			String s = "0000000" + accountNumInt;
			accountNumber = s.substring(s.length() - 8);
		} while( !(exists(accountNumber)));
		return accountNumber;
	}
	
	public static boolean exists(String accountNumber) {
		for( int i = 0; i < numberOfAccounts; i++) {
			if( accountsList.get(i).getAccountNumber().equals(accountNumber))
				return true;
		}
		return false;
	}
	
	public void deposit(String accountNumber, double amount) throws
			AccountErrorException, AmountBelowZeroException {
		if( exists(accountNumber)) {
			try {
				accountsList.get(getIndexOfAccount(accountNumber)).deposit(
						amount);
			} catch( AmountBelowZeroException ex) {
				throw ex;
			}
		} else {
				throw new AccountErrorException("Account " + accountNumber +
						" is invalid");
			}
		}
	
	public void withdraw(String accountNumber, double amount) throws
			AccountErrorException, AmountBelowZeroException,
			OverdraftWarningException {
		if( exists(accountNumber)) {
			try {
				accountsList.get(getIndexOfAccount(accountNumber)).withdraw(
						amount);
			} catch( AmountBelowZeroException ex) {
				throw ex;
			} catch( OverdraftWarningException ex) {
				throw ex;
			}	
		} else {
			throw new AccountErrorException("Account " + accountNumber +
					" is invalid");
		}
	}
		
	public void addInterest(String accountNumber, double annualInterestRate,
			double balance) throws AccountErrorException {
		if( exists(accountNumber)) {
			accountsList.get(getIndexOfAccount(accountNumber)).addMonthlyInterest
				(annualInterestRate, balance);
		} else {
			throw new AccountErrorException("Account " + accountNumber +
					" is invalid.");
		}
	}
	
	public double getBalance(String accountNumber) throws AccountErrorException {
		if( exists(accountNumber)) {
			return accountsList.get(getIndexOfAccount(accountNumber)).getBalance();
		} else { 
			throw new AccountErrorException("Account " + accountNumber +
					" is invalid.");
		}
	}
	
	public void close(String accountNumber) throws AccountErrorException {
		if( exists(accountNumber)) {
			accountsList.remove(getIndexOfAccount(accountNumber));
		} else {
			throw new AccountErrorException("Account " + accountNumber +
					" is invalid.");
		}
	}
	
	private int getIndexOfAccount(String accountNumber) {
		int index = 0;
		for( int i = 0; i < numberOfAccounts; i++) {
			if( accountNumber.equals(accountsList.get(i).getAccountNumber()))
				index = i;
		}
		return index;
	}
	
	public double checkCashed(String accountNumber, String checkNumber, 
			double amount) throws AccountErrorException, OverdraftWarningException, AmountBelowZeroException, InvalidCheckException {
		if(exists(accountNumber)) {
			try {
				accountsList.get(getIndexOfAccount(accountNumber)).cashCheck(checkNumber,amount);
			} catch (OverdraftWarningException ex){
				throw ex;
			} catch (AmountBelowZeroException ex){
				throw ex;
			} catch (InvalidCheckException ex){
				throw ex;
			}
			return this.balance;
		} else {
			throw new AccountErrorException("Account " + accountNumber +
					" is invalid.");
		}
	}
	
	public double paymentMade(String accountNumber, double amount) throws 
			AccountErrorException, OverdraftWarningException, AmountBelowZeroException {
		if(exists(accountNumber)) {
			try {
				accountsList.get(getIndexOfAccount(accountNumber)).makePayment(amount);
			} catch (OverdraftWarningException ex){
				throw ex;
			} catch (AmountBelowZeroException ex){
				throw ex;
			}
			return this.balance;
		} else {
			throw new AccountErrorException("Account " + accountNumber +
					" is invalid.");
		}
	}
}
Java Code:
public class Account {
	private String accountHolder;
	protected double balance;
	protected double annualInterestRate;
	private String accountNumber;
	
	/**Create an account with the required info */
	public Account(String accountNumber, String accountHolder, double balance, double annualInterestRate) {
		this.accountNumber = accountNumber;
		this.accountHolder = accountHolder;
		if(balance < 0) {
			balance = 0;
			this.balance = balance;
		} else 
			this.balance = balance;
		this.annualInterestRate = annualInterestRate;
	}
	
	public void setAccountNumber(String accountNumber){
		this.accountNumber = Bank.createAccount();
	}
	
	public String getAccountNumber() {
		return this.accountNumber;
	}
	
	public void setAccountHolder(String accountHolder) {
		this.accountHolder = accountHolder;
	}
	
	public String getAccountHolder() {
		return this.accountHolder;
	}
	
	public void setAnnualInterestRate(double annualInterestRate) {
		this.annualInterestRate = annualInterestRate;
	}
	
	public double getAnnualInterestRate() {
		return this.annualInterestRate;
	}
	
	public void deposit(double amount) throws AmountBelowZeroException {
		if(amount > 0) {
			this.balance += amount;
		} else {
			this.balance = this.balance;
			throw new AmountBelowZeroException("Deposit amount cannot be" +
					" negative or zero");
		}
	}
	
	public void withdraw(double amount) throws AmountBelowZeroException,
			OverdraftWarningException {
		if(amount <= 0) {
			this.balance = this.balance;
			throw new AmountBelowZeroException("Withdrawal amount cannot be" +
					" zero or negative");
		} else if(amount > this.balance) {
			this.balance = this.balance;
			throw new OverdraftWarningException("There is not enough in the" +
					" account for this transaction.");
		} else {
			this.balance -= amount;
		}
	}
	
	public double addMonthlyInterest(double annualInterestRate, double balance) {
		return balance + (balance * (annualInterestRate / 1200));
	}

	public double getBalance() {
		return this.balance;
	}
	
	public void cashCheck(String checkNumber, double amount) throws 
			InvalidCheckException, AmountBelowZeroException, OverdraftWarningException {
		if(checkNumber == null || checkNumber == "") {
			throw new InvalidCheckException("That check does not exist for this " +
					"account.");
		} else if( amount <= 0) {
			throw new AmountBelowZeroException("Check amount cannot be " +
					"zero or negative.");
		} else if(amount > this.balance) {
			throw new OverdraftWarningException("There is not enough in the " +
					"account for this transaction");
		} else { 
			this.balance -= amount;
		}
	}
		

	public void makePayment(double amount) throws AmountBelowZeroException,
			OverdraftWarningException {
		if( amount <= 0) {
			throw new AmountBelowZeroException("Payment cannot be zero or negative.");
		} else if(amount > this.balance) {
			throw new OverdraftWarningException("Payment exceeds the balance of the loan.");
		} else {
			this.balance -= amount;
		}
	}
}
Java Code:
public class SavingsAccount extends Account {
	private double annualInterestRate;
	private double monthlyInterestRate;
	
	public SavingsAccount(String accountNumber, String accountHolder, 
			double balance, double annualInterestRate) {
		super(accountNumber, accountHolder, balance, annualInterestRate);
		this.annualInterestRate = annualInterestRate;
	}
	
	public double getAnnualInterestRate() {
		return this.annualInterestRate;
	}
	
	public void setAnnualInterestRate() {
		this.annualInterestRate = annualInterestRate;
	}
	
	@Override
	public double addMonthlyInterest(double annualInterestRate, double balance) {
		return balance + (balance * (annualInterestRate / 1200));
	}
	
	public double getBalance() {
		return this.balance;
	}
	
	@Override
	public void deposit(double amount) throws AmountBelowZeroException {
		if(amount > 0) {
			this.balance += amount;
		} else {
			this.balance = this.balance;
			throw new AmountBelowZeroException("Deposit amount cannot be" +
					" negative or zero");
		}
	}
	
	@Override
	public void withdraw(double amount) throws AmountBelowZeroException,
			OverdraftWarningException {
		if( amount <= 0) {
			this.balance = this.balance;
			throw new AmountBelowZeroException("Withdrawal amount cannot be" +
					" zero or negative.");
		} else if( amount > this.balance) {
			this.balance = this.balance;
			throw new OverdraftWarningException("There is not enough in the " +
					"account for this transaction.");
		} else {
			this.balance -= amount;
		}
	}
}
Java Code:
public class LoanAccount extends Account {
	private double annualInterestRate;
	private double monthlyInterestRate;
	
	public LoanAccount(String accountNumber, String accountHolder, double balance, double annualInterestRate) {
		super(accountNumber, accountHolder, balance, annualInterestRate);
		this.annualInterestRate = annualInterestRate;
	}
	
	public double getAnnualInterest() {
		return this.annualInterestRate;
	}
	
	public void setAnnualInterestRate() {
		this.annualInterestRate = annualInterestRate;
	}
	
	@Override
	public double addMonthlyInterest(double annualInterestRate, double balance) {
		return balance + (balance * (annualInterestRate / 1200));
	}
	
	@Override
	public void makePayment(double amount) throws AmountBelowZeroException, OverdraftWarningException {
		if( amount <= 0) {
			throw new AmountBelowZeroException("Payment cannot be zero or negative.");
		} else if(amount > this.balance) {
			throw new OverdraftWarningException("Payment exceeds the balance of the loan.");
		} else {
			this.balance -= amount;
		}
	}
}
Java Code:
public class CheckingAccount extends Account {
	private double overdraftLimit;
	
	public CheckingAccount(String accountNumber, String accountHolder, 
			double balance, double annualInterestRate) {
		super(accountNumber, accountHolder, balance, annualInterestRate);
	}
	
	public double getOverdraftLimit() {
		return this.overdraftLimit;
	}
	
	@Override
	public void cashCheck(String checkNumber, double amount) throws 
			InvalidCheckException, AmountBelowZeroException, OverdraftWarningException {
		if(checkNumber == null || checkNumber == "") {
			throw new InvalidCheckException("That check does not exist for this " +
					"account.");
		} else if( amount <= 0) {
			throw new AmountBelowZeroException("Check amount cannot be " +
					"zero or negative.");
		} else if(amount > this.balance - overdraftLimit) {
			throw new OverdraftWarningException("There is not enough in the " +
					"account for this transaction");
		} else { 
			this.balance -= amount;
		}
	}
	
	@Override
	public void deposit(double amount) throws AmountBelowZeroException {
		if( amount > 0) {
			this.balance += amount;
		} else {
			throw new AmountBelowZeroException("Deposit amount cannot be" +
					" negative or zero.");
		}
	}
	
	@Override
	public void withdraw(double amount) throws AmountBelowZeroException,
			OverdraftWarningException {
		if( amount <= 0) {
			this.balance = this.balance;
			throw new AmountBelowZeroException("Withdrawal amount cannot be" +
					" zero or negative.");
		} else if( amount > this.balance - overdraftLimit) {
			this.balance = this.balance;
			throw new OverdraftWarningException("There is not enough in the " +
					"account for this transaction.");
		} else {
			this.balance -= amount;
		}
	}
	
	
}
Java Code:
public class BankController {
	private State currentState;
	
	public BankController() {
		this.currentState = State.CLOSED;
	}
	
	public State getState() {
		return this.currentState;
	}
	
	public void changeState() {
		if(currentState.equals(State.CLOSED)) {
			this.currentState = State.OPEN;
		} else 
			this.currentState = State.CLOSED;
	}
	
	//TODO
//	Open Bank
//	Creat Account
//	Close Account
//	Deposit to Account
//	Withdraw from Account
//	Cash Check
//	Apply monthly interest to Savings
//	Charge monthly interest on Loans
//	Close Bank
}
Java Code:
public enum AccountType {
	CHECKING,
	SAVINGS,
	LOAN
}
Java Code:
public enum State {
	OPEN,
	CLOSED
}
I don't know if I'm using @Override too much/ too little (correct at all?)
If I've got the right setters and getters
How to create the subclasses and use them in the ArrayList
How to even create the BankController.

I know this is a ton of code to dump at once, but if anyone can take a look and maybe steer me in the right directions, I'd appreciate it.

Thanks.