Mechanics
- A class hierarchy can be developed by putting common attributes and behaviors of related classes into a single class called a superclass.
- The keyword
extends
is used to establish an inheritance relationship between a subclass and a superclass. A class can extend only one superclass.
- Classes that
extend
a superclass, called subclasses, can draw upon the existing variables and behaviors of the superclass without repeating these in the code.
- Class
S
should only extend T
if there is an “is-a” relationship between S and T. (If an S
isn’t a T
but they’re related it may be that there should be a “has-a” relationship expressed by one class having an instance variable that holds a reference to an instance of the other class.)
- While a class can only directly extend one class it is also, indirectly, subclass of all the classes its direct suprclass is a subclass of.
- The
Object
class in the java.lang
package is the direct or indirect superclass of all other classes in Java.
- Classes that do not explicitly extend another class, implicitly extend
Object
. (Other, than Object
which is special.)
- All classes inherit from
Object
the methods boolean equals(Object other)
and String toString()
which are described in the [AP Java Quick Reference].
- Subclasses of
Object
often override the equals
and toString
methods with class-specific implementations.\note{Correctly implementing an overridden version of equals
is actually surprisingly hard but how to do so is not part of the AP curriculum.}
Constructors in inheritance hierarchies
- Constructors are not inherited.
- Every constructor must call a superclass constructor as the first thing it does. This can either be explicit, using the keyword
super
and passing appropriate arguments, or implicit by letting the compiler insert a call to the superclass’s no-argument constructor, if there is one.
- Regardless of whether the superclass constructor is called implicitly or explicitly, the process of calling superclass constructors continues until
java.lang.Object
’s no-arg constructor is called. At this point, all of the constructors within the hierarchy execute, beginning with the Object
constructor. This ensures that before any code runs in a class all of it’s inherited instance variables have been properly initialized.
- The actual parameters passed in the call to the superclass constructor provide values that the constructor can use to initialize the instance variables defined in the superclass.
Inherited methods
- A subclass inherits all the
public
methods of its superclass as public
methods in the subclass.
- A
public
method written in a subclass with the same method signature as a public method in the superclass \i{overrides} the parent class method.
- Subclasses can extend the behavior of their superclass by overriding existing methods or by adding additional methods or instance variables that are not present in the superclass.
- In a subclass, the superclass version of an overridden method, say
foo
can be called as super.foo()
passing appropriate parameters as in any method call.
- The compiler will only allow method calls to non-
static
methods that exist in the compile-time type of object on which the method is being called, either because the method is defined in that class or inherited from a superclass.
- At run-time, the actual type of the object on which a non-
static
method is invoked determines exactly what method is run.
Types and inheritance
- Anywhere an instance of type
T
is required (assigning to a variable declared to be of type T
, as a method argument that requires a T
, as an element of a T[]
array or an ArrayList<T>
, etc.) we can also use an instance of S
if S
is a direct or indirect subclass of T
.
- Using an instance of a subclass in the place of the superclass is what allows for the possibility of polymorphism, where the actual class of an object determines what version of an overridden method is invoked.