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.
Similarly, a RewardCard
is a specialization
of CreditCard
. A RewardCard
has all of the public fields and attributes of
CreditCard
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
.
As far as the client is concerned, a subclass has all of its superclass methods. These methods are shown in the API under sections labelled "Methods inherited from class ...". To find detailed information about such methods, the client must consult the APIs of the superclasses.
A subclass is also allowed to redefine a superclass method. Redefining a superclass method is called method overriding. If a subclass overrides a method, that method appears in the subclass "Method Summary" section of the API.
An overridden method has the exact same signature and return type as the superclass method (an overriding method can also return a subtype of the type returned by the overridden method).
A subclass cannot override a static
method
in the superclass; something else happens instead
(left vague intentionally).
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.