slanted W3C logo

Day 23 — Inheritance

Aggregation and composition result in new classes that are made up of other classes (the aggregation has references to other objects).

Inheritance results in a new class that is an extension of another class.

Inheritance

In object-oriented programming, inheritance allows an implementer to create new classes based on an existing class. In Java, you tell if a class inherits from another class by looking for the keyword extends at the top the API:

public final class String extends Object
public class PrintStream extends FilterOutputStream

public class FilterOutputStream extends OutputStream

public abstract class OutputStream extends Object
public class RewardCard extends CreditCard

Inheritance

Inheritance describes the is-a relationship between classes. The header:

public final class String extends Object

means that a String is-an Object. From the client's point of view, this means that String has every public field and method (but not constructors) that Object has.

In fact, in Java, every class ultimately inherits from Object. If you look at the API of Object you will see all of the obligatory methods (and more) that were mentioned in Chapter 4.

Terminology

Inheritance is One Way

Note that inheritance is a one way relationship. A String is-an Object but the opposite is not true: an Object is not a String.

Inheritance is Specialization

You can think of String as being a specialization of Object. A String has all of the public fields and attributes of Object plus more.

Similarly, a RewardCard is a specialization of CreditCard. A RewardCard has all of the public fields and attributes of CreditCard plus more.

UML Diagrams

A UML diagram indicates inheritance relationships using a line with an arrow joining the two classes:


The direction of the arrow is important; it points from the subclass to the superclass.

Notice that RewardCard inherits from CreditCard which in turn inherits from Object. This means that a RewardCard is-a CreditCard and is-an Object.

Siblings

There is no structural relationship between siblings. A and B have a common parent R, but are otherwise unrelated.


Similarly, K and L are unrelated (except that they share a common parent A and a common grandparent B).

Multiple Inheritance

Java does allow multiple inheritance; thus a child class can have only one immediate parent class.


Subclass API: Constructors

Constructors are never inherited.


The client must use a subclass constructor.

RewardCard rc = new RewardCard(123456, "Miss Take");

Subclass API: Methods

A subclass inherits all of the public methods of its superclass. A client can invoke the inherited methods in the usual way:

// rc is a RewardCard

double youOwe = rc.getBalance();
double canSpend = rc.getLimit() - youOwe;

A client needs to refer to the superclass API for documentation on inherited methods.

Subclass API: Methods

A subclass can define a new public method that is not in the superclass. A client can invoke the new method in the usual way:

// rc is a RewardCard

int points = rc.getPointBalance();
rc.redeem(points);

A client needs to refer to the subclass API for documentation on new methods defined by the subclass.

Subclass API: Methods

A subclass can define a new public method that has the same signature as a method inherited from the superclass. Such a method is said to override the inherited method. A client can invoke the overridden method in the usual way:

// rc is a RewardCard

// the current point balance
int points = rc.getPointBalance();

// go shopping at Costco
boolean success = rc.charge(100.00);

// do we have more points?
output.println(rc.getPointBalance() > points);

Notice that charge has been specialized for RewardCard to accrue reward points.

Inheriting Methods: RewardCard

The RewardCard API indicates that it has many methods inherited from CreditCard that are not overridden:

getBalance
getExpiryDate
getIssueDate
getLimit
getName
getNumber
hashCode
isSimilar
pay
setExpiryDate
setLimit

Overriding Methods: RewardCard

Less obvious is the fact that RewardCard has overridden four methods from CreditCard:

charge
credit
equals
toString

Why did the implementer of RewardCard decide to override these methods? Because these methods behave differently for RewardCard than they do for CreditCard.

Adding Methods: RewardCard

A RewardCard is a CreditCard but it can do things related to its reward points that CreditCard cannot. To support this added behavior, the implementer has added extra methods to RewardCard:

getPointBalance
isSimilar

Notice that a method named isSimilar is also defined in CreditCard but that version has a CreditCard reference as a parameter. The RewardCard version takes a RewardCard reference as a parameter. This is an example of an overloaded method, not an overridden method. RewardCard has both versions of the isSimilar method.

How Many Methods?

The total number of public methods in a class is:

number of inherited methods
           +
  number of new methods
           -
number of overridden methods