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.
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 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.
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
.
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.
String
can do anything that
an Object
can do plus more.Similarly, a RewardCard
is a specialization
of CreditCard
. A RewardCard
has all of the public fields and attributes of
CreditCard
plus more.
RewardCard
can do anything that
a CreditCard
can do plus more.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
.
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
).
Java does allow multiple inheritance; thus a child class can have only one immediate parent class.
Constructors are never inherited.
The client must use a subclass constructor.
RewardCard rc = new RewardCard(123456, "Miss Take");
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.
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.
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.
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
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
.
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.
The total number of public methods in a class is:
number of inherited methods + number of new methods - number of overridden methods