Overriding methods and parameter types
In the reduce method, the parameter must be Set<? extends Algorithm<List<T>,Integer>> Set<? extends Algorithm<List<T>,Integer>> . Should it accept any Set<? extends Algorithm<List<T>,Integer>> Set<? extends Algorithm<List<T>,Integer>> , and not just a Set<LinearSearch<T>> . You cannot narrow down a parameter type by overriding a method.
JLS, section 8.4.8.1 details the signatures of overriding methods:
The instance method m1 declared in class C overrides the other instance method m2 declared in class A if all of them are true:
C is a subclass of A.
The signature m1 is a sub-sticker (§8.4.2) of the signature m2.
Or:
m2 is public, secure, or declared with default access in the same package as C, or
m1 redefines the method m3 (m3 different from m1, m3 different from m2) such that m3 redefines m2.
Here, “sub-heading” refers to matching parameter types after type erasure.
Overriding Methods and Return Types
But why does the map method work? Because Java allows the developer to narrow the return type of overriding methods in subclasses.
A different part of JLS, 8.4.5 , covers return types in overriding methods:
The return types may vary depending on the methods that override each other if the return types are reference types. The concept of a return-type substitution function supports covariant returns, that is, specialization of the return type to a subtype.
Declaring a method d1 with return type R1 is a return type-replaceable for another method d2 with return type R2, if and only if the following conditions are true:
If R1 is invalid, then R2 is invalid.
If R1 is a primitive type, then R2 is identical to R1.
If R1 is a reference type, then:
R1 is either a subtype of R2, or R1 can be converted to a subtype of R2 by unverified conversion (§5.1.9) or
R1 = | R2 |
(my accent)