1. Technology

Using Inheritance

By

Before you use inheritance consider the relationship between the class to be extended and the class doing the extending. Always ask yourself if inheritance is the right relationship for the two classes.

A way to test for inheritance is to ask the "is-a" question. For example, in this article I will be extending a class that represents a simple bank account, to create a class that represents a bank account with an overdraft limit. In this case it's easy to see that the overdraft account is a kind of a bank account, that there is common functionality between the two classes and that the overdraft account will be a more specialized version of a bank account. The only difference between the two classes is the overdraft account will limit the amount of money that can be withdrawn and it will charge an overdraft fee every time a withdrawal is made whilst the account is using the overdraft.

Note: In an application that deals with money calculations you should use the BigDecimal class. However, as the focus of this article is inheritance, the double datatype has been used for the sake of simplicity.

Defining a Superclass

First lets define the simple bank account class. The "Account" class is going to be the superclass in the relationship between the two classes:

 public class Account {
 
   private double balance;
 
   public Account(double startingBalance)
   {
     this.balance = startingBalance;
   }
 
   public void withdrawMoney(double amount)
   {
     this.balance -= amount;
   }
 
   public void depositMoney(double amount)
   {
     this.balance += amount;
   }
 
   public double getBalance()
   {
     return this.balance;
   } 
 } 

It's a very basic account class. It holds a balance, allows that balance to be queried, and amounts can be deposited or withdrawn from the account. In the real world, a bank account with no limit to how much money can be withdrawn from it is not likely to be popular with a bank! Still, it shows why we want to create a class that represents an account with an overdraft limit.

Defining a Subclass

The overdraft account also needs needs a balance, a way to query that balance, and the ability to withdraw or deposit money. Therefore it makes sense for the overdraft account to inherit the state and behaviors of the Account class. It will be the subclass in the relationship between the two classes.

In the Java programming language, a class can employ inheritance by using the "extends" keyword. It makes sure the state and behaviors of the Account class are automatically available to the "OverdraftAccount" class:

 public class OverdraftAccount extends Account {
 
   public OverdraftAccount(double balance)
   {
     super(balance);
   }
 } 

Notice the use of the "super" keyword. It gives the subclass access to the superclass definition. In the OverdraftAccount constructor method it's used to call the constructor method of the Account class. The line:

 super(balance); 
allows the OverdraftAccount class to store its balance using the state defined in the Account class. If that sounds confusing remember that a class definition is the blueprint for an object. By creating an extending class definition it's the same as adding an extension to the original blueprint. When an instance of an OverdraftAccount object is created it will be the combination of both class definitions.

At the moment the OverdraftAccount is almost exactly the same as the Account class. We can create an instance of it and be able to deposit or withdraw money:

 //create an instance of an ordinary account
 Account bobsAccount = new Account(10);
 bobsAccount.depositMoney(50);
 bobsAccount.withdrawMoney(1000);
 System.out.printf("Bob's account balance is %.2f%n", bobsAccount.getBalance());

 //create an instance of the overdraft account
 OverdraftAccount jimsAccount = new OverdraftAccount(15.05);
 jimsAccount.depositMoney(50);
 jimsAccount.withdrawMoney(10);
 System.out.printf("Jim's account balance is %.2f%n", jimsAccount.getBalance());
 
 The output is:
 Bob's account balance is -940.00
 Jim's account balance is 55.05 

Even though the depositMoney and getBalance behaviors aren't explicitly defined in OverdraftAccount they can be used because they are inherited from Account. The true power of inheritance becomes apparent when we start extending the functionality of the subclass:

 public class OverdraftAccount extends Account {
 
   private double overdraftLimit;
   private double overdraftFee;
 
   public OverdraftAccount(double balance, double limit, double overdraftFee)
   {
     super(balance);
     this.overdraftLimit = limit;
     this.overdraftFee = overdraftFee;
 }
 
   public void setOverdraftLimit(double limit)
   {
     this.overdraftLimit = limit;
   }
 
   public double getAvailableFunds()
   {
     return super.getBalance() + overdraftLimit;
   }
 } 

Now the OverdraftAccount's state holds an overdraft limit and an overdraft fee. There are new behaviors defined to allow the setting of the overdraft limit and to see the available funds for the account. Again notice the use of the super keyword. If you look back at the Account class definition you will see that the balance field is defined with the private keyword. This means that even though OverdraftAccount is a subclass of the Account it can't access the field directly. This is normal for inheriting classes because we still want to enforce data encapsulation. The super keyword provides access to the getBalance() accessor method.

Continue on to the next page to learn about modifying superclass behaviors.

Related Video
Using Meta Data for Search
  1. About.com
  2. Technology
  3. Java
  4. Java Syntax
  5. Working With Objects
  6. Using Inheritance: Defining a Superclass and Subclass

©2014 About.com. All rights reserved.