Chapter 13

Inheritance


Chapter Goals

An Introduction to Inheritance

An Inheritance Diagram

An Introduction to Inheritance

Layout of a Subclass Object

Syntax 13.1: Inheritance

  class SubclassName extends SuperclassName
{
   methods
   instance fields

}

Example:

 
public class SavingsAccount extends BankAccount
{
   public SavingsAccount(double rate)
   {
      interestRate = rate;
   }

   public void addInterest()
   {
      double interest = getBalance() * interestRate / 100;
      deposit(interest);
   }

   private double interestRate;
}

Purpose:

To define a new class that inherits from an existing class, and define the methods and instance fields that are added in the new class.

Self Check

  1. Which instance fields does an object of class SavingsAccount have?
  2. Name four methods that you can apply to SavingsAccount objects
  3. If the class Manager extends the class Employee, which class is the superclass and which is the subclass?

Answers

  1. Two instance fields: balance and interestRate.
  2. deposit, withdraw, getBalance, and addInterest.
  3. Manager is the subclass; Employee is the superclass.

Inheritance Hierarchies

Inheritance Hierarchies Example: Swing hierarchy

A Simpler Example: Hierarchy of Bank Accounts

Self Check

  1. What is the purpose of the JTextComponent class in Figure 4?
  2. Which instance field will we need to add to the CheckingAccount class?

Answers

  1. To express the common behavior of text fields and text components.
  2. We need a counter that counts the number of withdrawals and deposits.

Inheriting Methods

Inheriting Instance Fields

Implementing the CheckingAccount Class

Inherited Fields are Private

Invoking a Superclass Method

Syntax 13.2: Calling a Superclass Method

  super.methodName(parameters)

Example:

  public void deposit(double amount)
{
   transactionCount++;
   super.deposit(amount);
}

Purpose:

To call a method of the superclass instead of the method of the current class

Implementing Remaining Methods

public class CheckingAccount extends BankAccount
{
   . . .
   public void withdraw(double amount)
   {
      transactionCount++;
      // Now subtract amount from balance
      super.withdraw(amount);
   }

   public void deductFees()
   {
      if (transactionCount > FREE_TRANSACTIONS)
      {
         double fees = TRANSACTION_FEE
            * (transactionCount - FREE_TRANSACTIONS);
         super.withdraw(fees);
      }
      transactionCount = 0;
   }
   . . .
   private static final int FREE_TRANSACTIONS = 3;
   private static final double TRANSACTION_FEE = 2.0;
}

Self Check

  1. Why does the withdraw method of the CheckingAccount class call super.withdraw?
  2. Why does the deductFees method set the transaction count to zero?

Answers

  1. It needs to reduce the balance, and it cannot access the balance field directly.
  2. So that the count can reflect the number of transactions for the following month.

Common Error: Shadowing Instance Fields

Subclass Construction

Syntax 13.3: Calling a Superclass Constructor

  ClassName(parameters)
{
   super(parameters);
   . . .
}

Example:

 
public CheckingAccount(double initialBalance)
{
   super(initialBalance);
   transactionCount = 0;
}

Purpose:

To invoke a constructor of the superclass. Note that this statement must be the first statement of the subclass constructor.

Self Check

  1. Why didn't the SavingsAccount constructor in Section 13.1 call its superclass constructor?
  2. When you invoke a superclass method with the super keyword, does the call have to be the first statement of the subclass method?

Answers

  1. It was content to use the default constructor of the superclass, which sets the balance to zero.
  2. No–this is a requirement only for constructors. For example, the SavingsAccount.deposit method first increments the transaction count, then calls the superclass method.

Converting Between Subclass and Superclass Types

Converting Between Subclass and Superclass Types

Converting Between Subclass and Superclass Types

Syntax 13.4: The instanceof Operator

  object instanceof TypeName

Example:

 
if (anObject instanceof BankAccount)
{
   BankAccount anAccount = (BankAccount) anObject;
   . . .
}

Purpose:

To return true if the object is an instance of TypeName (or one of its subtypes), and false otherwise

Self Check

  1. Why did the second parameter of the transfer method have to be of type BankAccount and not, for example, SavingsAccount?
  2. Why can't we change the second parameter of the transfer method to the type Object?

Answers

  1. We want to use the method for all kinds of bank accounts. Had we used a parameter of type SavingsAccount, we couldn't have called the method with a CheckingAccount object.
  2. We cannot invoke the deposit method on a variable of type Object.

Polymorphism

Polymorphism

File AccountTester.java

File BankAccount.java

File CheckingAccount.java

File SavingsAccount.java

Output

Mom's savings balance = $7035.0
Harry's checking balance = $1116.0

Self Check

  1. If a is a variable of type BankAccount that holds a non-null reference, what do you know about the object to which a refers?
  2. If a refers to a checking account, what is the effect of calling a.transfer(1000, a)?

Answers

  1. The object is an instance of BankAccount or one of its subclasses.
  2. The balance of a is unchanged, and the transaction count is incremented twice.

Access Control

Recommended Access Levels

Self Check

  1. What is a common reason for defining package-visible instance fields?
  2. If a class with a public constructor has package access, who can construct objects of it?

Answers

  1. Accidentally forgetting the private modifier.
  2. Any methods of classes in the same package.

Object: The Cosmic Superclass

Overriding the toString Method

Overriding the toString Method

Overriding the equals Method

Overriding the equals Method

Self Check

  1. Should the call x.equals(x) always return true?
  2. Can you implement equals in terms of toString? Should you?

Answers

  1. It certainly should–unless, of course, x is null.
  2. If toString returns a string that describes all instance fields, you can simply call toString on the implicit and explicit parameters, and compare the results. However, comparing the fields is more efficient than converting them into strings.

Overriding the clone Method

The Object.clone method

Scripting Languages