I want to declare a method in an interface where the parameter of the method defined in implementing classes can be a subtype of a specific java class for example:
interface Processor{
processRequest( Request r);
}
public class SpecialRequest extends Request{...}
public class SpecialProcessor implements Processor{
processRequest(SpecialRequest r){...}
}
but I get errors in the SpecialProcessor because it doesn't properly implement the Processor interface. What can I change in the Processor interface to allow the definition in the SpecialProcessor to work?
In Java, Sis a subtype of T if S extends or implements T. Subtyping is transitive, meaning that if R is a subtype of S, then R is also a subtype of T (T is the super type of both Sand R). Here are some examples: - Integer is a subtype of Number. - ArrayList<E> is a subtype of Collection<E>
Subclass is not the same as subtype. You might create subclasses that are not subtypes.
You can subtype a generic class or interface by extending or implementing it. The relationship between the type parameters of one class or interface and the type parameters of another are determined by the extends and implements clauses.
Although Integer is a subtype of Number, List<Integer> is not a subtype of List<Number> and, in fact, these two types are not related.
You can type Processor
:
public interface Processor<R extends Request> {
void processRequest(R r);
}
public class SpecialProcessor implements Processor<SpecialRequest> {
public void processRequest(SpecialRequest r) {
...
}
}
That's right - remember that a caller shouldn't know what specific implementation of the interface is being used. They just know that they can pass a Request
(any Request) to processRequest
, whereas your implementation is imposing a stricter constraint on the argument that would cause certain method calls not to be type-correct.
If you want to do this, you'll need to add a generic parameter to the interface, something like the following:
interface Processor<R extends Request> {
void processRequest(R r);
}
public class SpecialProcessor implements Processor<SpecialRequest> {
public void processRequest(SpecialRequest r) { ... }
}
This way, callers that want to pass in "normal" requests will have to declare a variable/field of type Processor<Request>
- and your SpecialProcessor no longer matches this bound, so cannot be assigned, and will correctly be rejected at compile-time. Callers that are dealing with special requests themselves can use a Processor<SpecialRequest>
variable/field, which your class can be assigned to.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With