15

I'm upgrading some code to Java 5 and am clearly not understanding something with Generics. I have other classes which implement Comparable once, which I've been able to implement. But now I've got a class which, due to inheritance, ends up trying to implement Comparable for 2 types. Here's my situation:

I've got the following classes/interfaces:

interface Foo extends Comparable<Foo>

interface Bar extends Comparable<Bar>

abstract class BarDescription implements Bar

class FooBar extends BarDescription implements Foo

With this, I get the error 'interface Comparable cannot be implemented more than once with different arguments...'

Why can't I have a compareTo(Foo foo) implemented in FooBar, and also a compareTo(Bar) implemented in BarDescription? Isn't this simply method overloading?

Edit: I have many classes which extend BarDescription. If I remove the type parameter for Comparable on Bar, leaving it in the raw state, then I get a bunch of compiler warnings when sorting all the classes which extend BarDescription. Would this be solved with the wildcards answer below? That answer looks quite complicated and difficult to understand for maintenance.

user26270
  • 6,904
  • 13
  • 62
  • 94
  • Same question, different case. You're looking for something called type erasure. – falstro Apr 21 '10 at 18:32
  • @row Something called wildcards. – Tom Hawtin - tackline Apr 21 '10 at 19:21
  • 3
    @codeman73: but you simply cannot do that in Java... Java doesn't support true parametric polymorphism. This is why when you focus on "OO" instead of "Java idiosynchrasies" the Java generics are mostly pointless: sure, they're fine for the "collections" and for procedural program (and hence fit well the mentality of 99% of the Java developers out there) but it simply is not OO at all. That's my biggest gripe with generics in Java: you cannot have both *Handable* and *Handable* and that renders generics **useless** from an OO point of view. – SyntaxT3rr0r Apr 21 '10 at 20:15
  • @codeman73: so you either focus on clean OO design and clean translation from OOA/OOD to OOP using the *other* type of polymorphism that Java offers or you think that Java idiosynchrasies are fun and interesting and waste time trying to "generify" your Java programs just to realize they simply don't cut it for anything else but the simplest "collections" case and the simplest inheritance scheme (neither having much to do with OO). The entry on Wikipedai talks a bit about parametric polymorphism an the Java generics: http://en.wikipedia.org/wiki/Type_polymorphism#Parametric_polymorphism – SyntaxT3rr0r Apr 21 '10 at 20:17
  • 3
    Or, to rephrase WizardOfOdds, Java generics are perfectly fine and helpful for 99% of Java applications, but don't fit with a particularly purist definition of OO. – DJClayworth Apr 21 '10 at 20:19
  • 1
    @DJClayworth: not at all... Parametric polymorpishm is working fine in a great many OO languages but is broken beyond repair an badly fuxx0red in Java (see the Wikipedia article)... Precisely for the reason that prompted the OP to ask his question. This is **not** about purity, it's about the **broken** "parametric polymorphism" provided by Java, while it's working **fine** in several other OO languages. – SyntaxT3rr0r Apr 21 '10 at 20:23

3 Answers3

15

Generics don't exist after bytecode has been compiled.

Restrictions from this: You can't implement / extend two or more interfaces / classes that would be same without the generic parameter and are different with the generic parameter.

What you could do if you really really want type safety is:

interface Foo<T extends Foo<?>> extends Comparable<T>
interface Bar<T extends Bar<?>> extends Comparable<T>
abstract class BarDescription<T extends Bar<?>> implements Bar<T>
class FooBar extends BarDescription<FooBar> implements Foo<FooBar>
mkorpela
  • 4,317
  • 2
  • 19
  • 21
  • This is sort of working. I'm still trying to wrap my head around it. Why do we need the > I wish I had made my original post with more concrete examples. – user26270 Apr 22 '10 at 15:01
  • Also, isn't it redundant to have interface Foo> ? Another issue is that I have many classes which extend BarDescription but not Foo, and now all these have to define the type for BarDescription and implement compareTo(AnotherBarDescription), such as : class AnotherBarDescription extends BarDescription – user26270 Apr 22 '10 at 15:28
  • Yes it is redundant .. but Java Generics have there problems. One big problem is inheritance (super type is ? instead of Object). For example Foo foo = new Foo() isn't allowed. – mkorpela Apr 23 '10 at 05:43
  • If you have objects that need to be compared with other objects that only implement Foo or Bar then I suggest that you use Jim Kileys answer and implement two Comparators (one for Foo and one for BarDescription). – mkorpela Apr 23 '10 at 05:47
8

I'd write a couple of Comparators and be done with it.

Jim Kiley
  • 3,632
  • 3
  • 26
  • 43
1

Having multiple implementations of generic interfaces would run into problems when you consider wildcards.

This does not depend upon erasure.

Tom Hawtin - tackline
  • 145,806
  • 30
  • 211
  • 305