I think the explanation is deficient. The compiler prints:
Code: Select all
BookList.java:8: error: name clash: add(Object) in BookList and add(E) in ArrayList have the same erasure, yet neither overrides the other
public boolean add(Object o) {
^
where E is a type-variable:
E extends Object declared in class ArrayList
That is, overriding is not possible, because the two methods have the same erasure. Note that the compiler replaces E with Object in the bytecode, because in generic ArrayList it's typed as "E extends Object". But because the compiler knows at compile-time that E really is Book, as intended by the programmer, this is NOT a valid override, because that would have to use the exact same type. For the same reasons associated with generics, the compiler cannot consider this an overload, because it would result in the same bytecode method.
This is my interpretation. Please correct, if anybody knows better. I believe the last sentence of the explanation "the overridden method can use a subclass for the parameters but not a superclass" is just plain wrong, like renatumb implied. Overriding is covariant for the return type but not for the parameters.
BTW I find this an extremely difficult question, if not the most difficult I encountered
