3

Shortly I came across an oddity, I can't explain to myself. The real-world problem is already worked around, I'm just curious if there is an satisfying answer I didn't find.

Imagine you have to write a class that implements the following interface from some framework you are using:

interface Interface1 {
    String method();
}

So far so good. Now you introduce a second framework and it would be rather useful if your class would implement a second interface:

interface Interface2 {
    Long method();
}

That's the point where the problem arises:

class ThatsTheProblem implements Interface1, Interface2 {
    public ???? method() {
        // ...
    }
}

Any ideas?

Just for your information: The real-world problem is based on an abstract-dao-pattern where some entities had Long ids, others had UUID ids.

blafasel
  • 1,091
  • 14
  • 25
  • 1
    @JigarJoshi that question looks for a name for that problem, not a solution. – Luiggi Mendoza Jun 25 '14 at 22:16
  • That described problem well, however http://stackoverflow.com/questions/2598009/method-name-collision-in-interface-implementation-java is exact duplicate – jmj Jun 25 '14 at 22:19

4 Answers4

4

Short answer: you can't.

What you can do is provide a view that implements one or the other interface. For instance:

public class OnePossibleSolution { // no "implements"

    private String interface1Method() {
        return "whatever";
    }

    public Interface1 asInterface1() {
        return new Interface1() {
            @Override
            String method() {
                return interface1Method();
            }
        }
    }

    // ditto for Interface2...

This is probably the most Java-idiomatic way to solve the problem. It's what Map does when you want to iterate over its elements, for instance. Rather than try to solve the problem of being an Iterable<K>, Iterable<V> and Iterable<Map.Entry<K,V>>, it provides three views:

  • keySet()
  • values()
  • entrySet()

Each of those returns a respective collection, which implements the appropriate Iterable<...> interface.

yshavit
  • 42,327
  • 7
  • 87
  • 124
0

Two of the components of a method declaration comprise the method signature—the method's name and the parameter types. These methods have the same signature, therefore cannot be implemented by one class.

Remember that in Java, you don't neccesary have to store the result of a method. If your ThatsTheProblem class compiled, and you had a class with this code, to which version of the method would invoke?

ThatsTheProblem ttp = new ThatsTheProblem();
ttp.method();
Andres
  • 10,561
  • 4
  • 45
  • 63
0

It is clearly impossible to create one object that implements two conflicting interfaces. However, it is possible for one object to provide two different facades, each implementing conflicting interfaces.

Note here that the two facades refer to common instance variables of the one object so they do, essentially, represent the same object.

public interface Interface1 {

    String method();
}

public interface Interface2 {

    Long method();
}

public class DiMorph {

    String forInterface1 = "Number nine";
    Long forInterface2 = 9L;

    public Interface1 asInterface1() {
        return new AsInterface1();
    }

    private class AsInterface1 implements Interface1 {

        @Override
        public String method() {
            return forInterface1;
        }

    }

    public Interface2 asInterface2() {
        return new AsInterface2();
    }

    private class AsInterface2 implements Interface2 {

        @Override
        public Long method() {
            return forInterface2;
        }

    }
}

public void testInterface1(Interface1 i1) {

}

public void testInterface2(Interface2 i2) {

}

public void test() {
    DiMorph m = new DiMorph();
    testInterface1 (m.asInterface1());
    testInterface2 (m.asInterface2());
}
OldCurmudgeon
  • 64,482
  • 16
  • 119
  • 213
0

To quote @Andreas, this is simply impossible.

Imagine you have two workers, Alice and Bob, with two managers, Cathy and Dave. Cathy expects Alice to implement the Work() method and return a Java application. Dave, on the other hand, expects Bob to implement the Work() method and return a C++ library. What your question suggests is to introduce a new worker Eric who can do the Work() of Alice and Bob at the same time. What actually happens is that Eric is too overloaded to compile.

Austin Mullins
  • 7,307
  • 2
  • 33
  • 48