3.3.1. Overriding
In our new ColorAttr class we have both overridden and overloaded the instance method setValue:
Overloading a method is what you have already learned: providing more than one method with the
same name but with different signatures to distinguish them.
•
Overriding a method means replacing the superclass's implementation of a method with one of your
own. The signatures must be identicalbut the return type can vary in a particular way, as discussed
below.
•
Overloading an inherited method simply means that you have added a new method, with the same name as,
but a different signature from, an inherited method. In ColorAttr we have gone from having one
setValue method to having two overloaded forms of the method.
public Object setValue(Object newValue) {
// ...
}
public ScreenColor setValue(ScreenColor newValue) {
// ...
}
This is no different from having overloaded forms of a method declared in the same class.
Overriding a method means that you have replaced its implementation so that when the method is invoked on
an object of the subclass, it is the subclass's version of the method that gets invoked. In the ColorAttr
class, we overrode the Attr class's setValue(Object) by providing a new setValue(Object)
method in the ColorAttr class that uses the super keyword to invoke the superclass's implementation and
then invokes decodeColor. The super reference can be used in method invocations to access methods
from the superclass that are overridden in this class. You'll learn about super in detail on page 89.
When you're overriding methods, the signature must be the same as in the superclassif they differ then it is an
overload, not an override. The return type of an overriding method is allowed to vary in a specific way: If the
return type is a reference type then the overriding method can declare a return type that is a subtype of that
declared by the superclass method. Because a reference to a superclass can always hold a reference to an
instance of a subclass, this variation is perfectly safeit is referred to as being a covariant return type. We'll see
a good example of this when we look at object cloning on page 101. If the return type is a primitive type, then
the return type of the overriding method must be identical to that of the superclass method. It is an error if two
methods differ only in return type and the compiler will reject your class.
For overriding in a varargs method, as with overloading (see page 60), a sequence parameter of type T... is
treated the same as a parameter of type T[]. This means that an overriding method can "convert" the last
array parameter to a sequence, without changing the signature of the method. This allows clients of the
subclass to invoke that method with a variable number of arguments. Defining an overriding method that
replaces a sequence with an array is allowed, but is strongly discouraged. This is confusing and not useful, so
don't do it.[1]
[1] In the JDK 5.0 release the javac compiler issues a (somewhat misleading) warning in
both cases. It is expected that the warning when converting to a sequence will be removed. It
is possible that in a future release converting from a sequence to an array will be an error.
The overriding methods have their own access specifiers. A subclass can change the access of a superclass's
methods, but only to provide more access. A method declared protected in the superclass can be
redeclared protected (the usual thing to do) or declared public, but it cannot be declared private or
have package access. Making a method less accessible than it was in a superclass would violate the contract of