-1

I would like to ask you why usage @Override in this case produces an error "Method does not override method from its superclass"? Why I cannot use instance of the class implemented an interface as a parameter and return type of the metod defined by same interface?

 public interface Request {
    //....
  }

  public interface Response {
    //....
  }

  public class MyRequest implements Request {
    //....
  }

  public class MyResponse implements Response {
    //....
  }

  public interface Order {
    Response cancel(Request request);
  }

  public class MyOrder implements Order {

    @Override
    public MyResponse cancel(MyRequest request) {
      return null;
    }

  }
jnemecz
  • 3,171
  • 8
  • 41
  • 77
  • 2
    Returning `MyResponse` is okay, but accepting only `MyRequest` is not: If you referred to a variable as `Order o = new MyOrder();`, you would expect `o.cancel(r)` to handle _any_ `Request r`, not just `MyRequest`. However, the return value being only `MyResponse` is okay: it will always be a `Response`. – Rogue Oct 28 '22 at 15:34
  • Does this answer your question? [Why are contravariant parameter types in Java not allowed for overriding?](https://stackoverflow.com/questions/12439649/why-are-contravariant-parameter-types-in-java-not-allowed-for-overriding) – Rogue Oct 28 '22 at 15:34

2 Answers2

1

The following would not work -- but inheritance requires it must.

class MyOtherRequest implements Request { ... }

MyOrder myOrder = new MyOrder();
Order order = myOrder; // okay because myOrder is a subtype of Order
order.cancel(new MyOtherRequest()); // unimplemented!

As a result, a subtype's method must accept all the possible values the supertype's method would accept -- not just a subset.

Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413
  • I see. So when I need to concrete parameter of my `MyRequest` implementation in `MyOrder#cancel`, I need to accept `Request` and cast it later to `MyRequest` myself, am I right? – jnemecz Oct 28 '22 at 15:38
  • Ideally if there's something you need in that method, `Request` would be able to return it, rather than relying on a concrete type. What's the specific information you're trying to retrieve from `MyRequest` that couldn't be abstracted within `Request`? – Rogue Oct 28 '22 at 15:40
  • It's because of many different implementation of remote API, every API requires different values so I wanted to solve it by concrete implementation of `Request` interface for every concrete external API. In other words - I would like to have every `Request` implementation as simple as possible for every implementation of `Order` interface. – jnemecz Oct 28 '22 at 15:44
  • You shouldn't do any casting. Instead, use generics so you have a type safe way of enforcing which orders can handle which requests. – Louis Wasserman Oct 28 '22 at 15:49
0

The problem is with the parameter to cancel.

public MyResponse cancel(MyRequest request) {
      return null;
}

You can't pass a supertype to a subtype (In this case Request object to MyRequest parameter) as the implementation of the subType may have other methods that the superType interface is unaware of.

WJS
  • 36,363
  • 4
  • 24
  • 39