/*
   The code that was common to both the
   SavingsAccount and CheckingAccount classes
   has been "factored out" into a BankAccount
   class. Now each of SavingsAccount and
   CheckingAccount extend BankAccount, so
   they still have access to the code that
   they have in common.

   This is our inheritance diagram.

                 BankAccount
                 /         \
                /           \
               /             \
     SavingsAccount       CheckingAccount
*/

class BankAccount
{
   double balance;

   public double deposit(double amount)
   {
      balance += amount;
      return balance;
   }

   public double withdraw(double amount)
   {
      balance -= amount;
      return balance;
   }
}


class SavingsAccount extends BankAccount
{
   double interestRate;

   public void compoundInterest()
   {
   }
}


class CheckingAccount extends BankAccount
{
   public void writeCheck(double amount, int checkNumber)
   {
   }
}


public class BankAccounts
{
   public static void main(String[] args)
   {
      BankAccount ba1 = new SavingsAccount();
      BankAccount ba2 = new CheckingAccount();

      SavingsAccount sa1 = new SavingsAccount();
      CheckingAccount ca1 = new CheckingAccount();

//    SavingsAccount sa2 = new CheckingAccount();   // Not allowed.
//    CheckingAccount ca2 = new SavingsAccount();   // Not allowed.

      sa1.compoundInterest();    // A savings account can compound interest.
      ca1.writeCheck(10, 1001);  // A checking account can process a check.

//    ba1.compoundInterest();   // Wrong! But why, since ba1 points to a savings account?
//    ba2.writeCheck(20, 1002); // Wrong! But why, since ba2 points to a checking account?

      ((SavingsAccount)ba1).compoundInterest();
      ((CheckingAccount)ba2).writeCheck(20, 1002);
   }
}
