Inheritance means that one class is "just like that other one, except ...". At least that's Drake's initial definition (p. 67); but we should really add that inheritance means one class is a kind of another, for example, as Dog is a kind of Mammal. Class hierarchies in programming originate from classification, which is a very natural and useful way of structuring thought.
This is a very important feature of OOP, right up there with objects as bundles of data and functions.
This example develops classes representing a simple telephone, a cell phone, and a voice mail service, as shown in the UML class diagram (needs improvement):
The CellPhone class inherits from Telephone and adds features: the ability to set a ring tone, and voice mail. Voice mail is implemented by delegating messages (method calls) to a VoiceMail object. There is also a Tester class for demonstrating the other three.
Here's a method call:
Overriding is about
a, the "receiver of the message".
Overloading is about
The Object class has the method
public boolean equals (Object that); // method 1
If in the Telephone class I had defined
then I would have been overloading, not overriding.
public boolean equals (Telephone that); // method 2
In the statement
method 2 will be run if the declared type of
Telephoneand the actual type of
xis Telephone; otherwise method 1 runs.
yis declared as
Objectbut is actually a
Telephone, we don't get the desired result.
y is declared
Object and is not a
Telephone, what happens?
CellPhoneconstructor) calls the constructor of its superclass (
Telephone) with one argument.
Calling the superclass constructor must be the first action of the constructor of the subclass. We can call a constructor with arguments:
If we don't write a call to a superclass constructor, the compiler will insert
super(a, b, c);
super()(with no arguments) for us, as the first statement.
Similarly, in the
ring we see
This calls the method
ring from the superclass,
Telephone, avoiding the need to repeat the same statements here.
super allows the subclass's method or constructor to use what the superclass has defined, but then add to it or embellish it in some way. But for a method, it does not have to be the first statement.
Drake: "Extending a class is similar to implementing an interface." (p. 69, last paragraph).
(p. 72) We can write either
Light bulb = new Light();
Light bulb = new ColoredLight();
and either way, we can safely write
but how it behaves depends on what type of object it (bulb) is. Dynamic dispatch here. [Note: we could even let the actual class be determined by user input at run time. Of course, the compiler cannot predict what the user will input!
Subclasses can have subclasses; see FlashingColoredLight in Fig. 3-7, 3-6, pp. 74, 73.
Inheritance is transitive: If class
A defines method
foo which is inherited by subclass
B, and if
C is a subclass of
C also inherits
The remaining two sections cover special topics related to inheritance: the Object class, packages, and access levels.
(Already covered in chapter 2)
Every object is an
Object is the default superclass in Java; i.e., if we don't declare that a class "
extends something" then "
extends Object" is implicit.
Some methods of the Object class are generally useful, either "as is" or by overriding:
public boolean equals (Object that) Behaves just like
== (so if you want different behavior, you override it)
public String toString() returns a string of the form
If we do not override the
toString methods, these are the behaviors we get.
A class in a named package has a "full name" (or "fully qualified name") which is completely unambiguous, e.g.,
Outside the package, we must use the fully-qualified name, except:
After the class or its package is imported into the current file: either
Creating a package:
Write the package declaration at the beginning of each file in the package:
Compound package names e.g.
Can we extend a class that's in another package?
java.lang.Object(implicitly or explicitly). We can do this for other packages and classes as well.
Access modifiers are Java reserved words that describe fields and methods (also classes and interfaces!) and provide information hiding. There are four access levels and three access modifier keywords:
private= accessible only within the class
protected), except in an interface, where the default is
protected= accessible within the package and to descendants (subclasses, direct or indirect) of the class.
public= accessible everywhere.