views:

101

answers:

2

Here's an example of what I'd like to be able to do (in Java):

interface MyInterface<E> {
  public void doSomething(E foo);
}

class MyClass implements MyInterface<ClassA>, MyInterface<ClassB> {
  public void doSomething(ClassA fooA) {
    ...
  }

  public void doSomething(ClassB fooB) {
    ...
  }
}

When I try to implement this, the compiler tells me that I can only implement MyInterface once in MyClass. I had assumed that MyInterface<ClassA> is treated as a different type compared to MyInterface<ClassB>, but apparently not. This seems like something that would be very useful, so I'm surprised by the error.

Update: Thanks for the help so far. As one of the comments pointed out, the above is abstract; the problem I am trying to solve is to implement the Observer pattern in such a way that an observer class declares those classes it observes via the interfaces it implements and also deals with changes in the objects it observes in class-specific methods. The advantage of using such an approach would be that it is clear from the interfaces a class implements which type of objects it observes, and so that compiler forces the programmer to explicitly implement the handling of changes to instances of those classes that are observed. So, the above abstract code might actually be something like the following:

interface IsObserverOf<E> {
  public void observedDidChange(E foo);
}

class MyClass implements IsObserverOf<Database>, IsObserverOf<Spreadsheet> {
  public void observedDidChange(Database database) {
    ...
  }

  public void observedDidChange(Spreadsheet spreadsheet) {
    ...
  }
}

Here, MyClass declares that it observes Database objects and Spreadsheet objects, and the compiler would—in an ideal world—mandate that the two different observedDidChange() methods must be implemented.

Thanks.

+5  A: 

Due to Type Erasure, the parameters to the generic bit of the interface disappear when compiled and run. So as far as Java is concerned, MyInterface<ClassA> and MyInterface<ClassB> are identical, and become just MyInterface when compiled. I suppose when they implemented generics, it would have been possible to handle the case that you want (different types for the method parameters) but how would Java handle a method where the generic parameter is used for return type:

interface Foo<T> {
    T getSomeObject();
}

The problem there is that you can't overload a method whose only difference is return type, so this would seriously limit the usefulness of being able to do something like implements MyInterface<ClassA|ClassB>.

Adam Batkin
I had the same problem a while ago. My conclusion is that Java's Generic sucks! Sun should have bit the bullet and gave us the real Generic.
Journeyman Programmer
They claim that the issue is compatibility with software/libraries pre-generics. Truth is, it is very impressive that you can run ancient software on modern JVMs, unmodified. We have a piece of complicated GUI software internally that was written for a pre-1.2 Windows JVM (yikes!) which runs perfectly well (unmodified) under (for example) a 64 bit 1.6 JVM on a Mac.
Adam Batkin
@Journeyman Programmer: out of curiosity, what OO languages do allow something like `class MyClass implements MyInterface<ClassA>, MyInterface<ClassB> ...` ?
Stephen C
@stephen C: C++
Chii
@stephen C: addendum: C++ using templates that is.
Chii
+5  A: 

Maybe you're looking for a Visitor Pattern (aka "double dispatch").

duffymo
+1: the right approach imho
dfa