0

Why I cannot do that? I get compilation error.

public interface A {

  void update(Object a);
}

public class B implements A{
     void update(Long a) {
     }

}

That is Java 8

I do not see here violating any OO principle.

That's really make my time difficult to implement a generic API...

(I try to get Generics out of the play because the generic API gets counter-intuitive)

Novemberland
  • 530
  • 3
  • 8
  • 25
  • Do you mean the other way around? `A.update(Long)` and `B.update(Object)`? Because right now this clearly is not type safe at all. – Sweeper Jan 07 '21 at 06:35
  • Right now this violates Liskov Substitution Principle. If you do mean `A.update(Long)` and `B.update(Object)`, have a look at [this](https://stackoverflow.com/questions/12439649/why-are-contravariant-parameter-types-in-java-not-allowed-for-overriding). – Sweeper Jan 07 '21 at 06:41
  • I do not think it violates Substitution Principle because Long is SubType of Object. Where ever you have an Object you can substitute it with it's subtype. – Novemberland Jan 07 '21 at 06:46
  • Substitutability is a principle in object-oriented programming stating that, in a computer program, if S is a subtype of T, then objects of type T may be replaced with objects of type S (i.e., an object of type T may be substituted with any object of a subtype S) without altering any of the desirable properties of the program (wikipedia) – Novemberland Jan 07 '21 at 06:57
  • ...which implies preconditions must not be strengthened in a subtype (this is also on wikipedia if you scroll down), and "strengthening preconditions (about what can `a` do)" is exactly what you are doing here. I realised it's kind of hard to argue for LSP directly, since there are no objects of interfaces. I'm writing an answer right now that shows how broken the code is. – Sweeper Jan 07 '21 at 07:02
  • I do not think any precondition is violated. You see a new method that's why you say they are strengthened, I see the "same" method. By strengthening the article means new signatures. If there was a recursive resolving of Substitution principle by design there would be not violation. – Novemberland Jan 07 '21 at 07:44
  • 1
    `A a = new B(); a.update("foo");` Does it work? If not, `B` is not a valid substitute for `A`. As simple as that. – Holger Jan 07 '21 at 13:49
  • As @Eran's answer seems a one way solution, I think this is the closest I am searching for in order to avoid those hardcoded if checks inside the implementations as it is a well known problem: https://en.wikipedia.org/wiki/Visitor_pattern Thanks for your answers. – Novemberland Jan 08 '21 at 11:09

2 Answers2

1

You get a compilation error because void update(Long a) does not implement void update(Object a).

You can implement it as follows:

public class B implements A {
    void update(Object o) {
        if (!(o instanceof Long)) {
            // possibly throw an exception
        }
        Long a = (Long) o;
        ...
    }
}
Eran
  • 387,369
  • 54
  • 702
  • 768
0

A class that implements an interface must implement all the methods declared in the interface. The methods must have the exact same signature (name + parameters) as declared in the interface. The class does not need to implement (declare) the variables of an interface. Only the methods.

Source:

http://tutorials.jenkov.com/java/interfaces.html#:~:text=A%20class%20that%20implements%20an,Only%20the%20methods.

Adnan Ahmed
  • 466
  • 1
  • 6
  • 15