THE Java™ Programming Language, Fourth Edition

(Jeff_L) #1

types must be the same.


Second, rather than requiring the same (or different) signatures we talk about override-equivalent signatures:
Two methods have override-equivalent signatures if their signatures are the same, or if the erasures of their
signatures are the same.


Using the new definitions, two methods are overloaded if they have the same name and do not have
override-equivalent signatures. Consider this class:


class Base {
void m(int x) {}
void m(T t) {}
void m(String s) {}


void m(N n) {}
void m(SingleLinkQueue q) {}
}

This defines five different overloads of the method m. Replacing each method's signature by its erasure, we
would get the following corresponding set of methods:


void m(int x) {}
void m(Object t) {}
void m(String s) {}
void m(Number n) {}
void m(SingleLinkQueue q) {}


It is an error for a class or interface to declare two methods with the same name and the same signature
erasure. Consequently, trying to define any of the following versions of m in Base would be an error:


void m(Object o) {}
void m(Number n) {}


void m(G g) {}
void m(SingleLinkQueue q) {}

In each case, the erasure of the signature matches the erasure of one of the other signatures.


A method in a subtype potentially overrides an accessible method in a super type if the two methods have the
same name and have override-equivalent signatures. We say "potentially overrides" because there is an
additional requirement to be met: The signature of the subclass method must be the same as that of the
superclass method, or it must be the same as the erasure of the signature of the superclass method. This
constraint makes overriding a "one-way street": A method without generic types can override a method with
generic types, but not the other way around. You are allowed to do this so that you can generify an existing
class without breaking previously existing subclasses that overrode methods.


Continuing with the previous example we can extend Base as follows:


class Derived extends Base {
void m(Integer i){} // new overload
void m(Object t) {} // overrides m(T t)
void m(Number n) {} // overrides m(N n)
}