Overriding Behaviors
Although a subclass inherits the state and behaviors of its superclass it's often the case that a behavior needs to be modified. Consider the behavior withdrawMoney. In the superclass Account there is no restriction on making a withdrawal. In the subclass OverdraftAccount we want to restrict the amount that can be withdrawn to the overdraft limit and charge a fee every time a withdrawal is made using the overdraft. This can be achieved by overriding the withdrawMoney behavior. Overriding a behavior means that when a behavior is used by an instance of the subclass object, the behavior of the subclass is called rather than the version in the superclass.
To override a behavior the subclass must define the method in exactly the same way as the superclass. The method signature and return type must match:
public void withdrawMoney(double amount)
{
double balance = super.getBalance();
if (balance - amount + this.overdraftLimit - overdraftFee > 0)
{
if (balance - amount < 0)
{
//only charge fee if account is overdrawn
super.withdrawMoney(amount + overdraftFee);
}
else
{
super.withdrawMoney(amount);
}
}
}
Now if we call the withdrawMoney behavior, the version defined in OverdraftAccount will be called:
OverdraftAccount jimsAccount = new OverdraftAccount(15.05,500,0.05);
jimsAccount.depositMoney(50);
jimsAccount.withdrawMoney(100);
System.out.printf("Jim's account balance is %.2f%n" + jimsAccount.getBalance());
System.out.printf("Jim's available funds are %.2f%n" + jimsAccount.getAvailableFunds();
JimsAccount.withdrawMoney(1000);
System.out.printf("Jim's available funds are %.2f%n" + jimsAccount.getAvailableFunds();
The output is:
Jim's account balance is -35.00
Jim's available funds are 465.00
Jim's available funds are 465.00
As you can see above, jimsAccount cannot withdraw an amount that will take the balance of the account over the overdraft.
Use a Subclass as a Superclass
A subclass can be treated as if it were a superclass if we only want to use the state and behaviors defined within the superclass. For example, imagine we have objects that are Account and OverdraftAccount types. If we want to loop through all the objects and return their balances, we can group them together as Account types because the behavior getBalance is defined in the Account superclass:
Account bobsAccount = new Account(10);
bobsAccount.depositMoney(50);
OverdraftAccount jimsAccount = new OverdraftAccount(15.05,500,0.05);
jimsAccount.depositMoney(50);
//create an array of Account objects
//we can include jimsAccount because we
//only want to treat it as an Account object
Account[] accounts = {bobsAccount, jimsAccount};
//for each account in the array display the balance
for (Account a:accounts)
{
System.out.printf("The balance is %.2f%n", a.getBalance());
}
The output is:
The balance is 60.00
The balance is 65.05

