4

Having this design :

interface Foo<T> {
   void doSomething(T t);
}

class FooImpl implements Foo<Integer> {
   //code... 
}

interface Bar extends Foo {
   //code...
}

class BarImpl extends FooImpl implements Bar {
     //code...
}

It gives me Compile Error :

The interface Foo cannot be implemented more than once with different arguments: Foo and Foo

a simple fix for this issue is :

interface Bar extends Foo<Integer> {
 // code...
}

Integer type in Bar interface is totally useless.

is there any better way to solve this issue ? any better design?

Thanks for your advices.

EDIT:

given solution:

> interface Bar<T> extends Foo<T> 

is ok, but its same as my previous solution. i don't need T type in Bar.

let me give a better sample:

interface ReadOnlyEntity {
}

interface ReadWriteEntity extends ReadOnlyEntity {
}

interface ReadOnlyDAO<T extends ReadOnlyEntity> {
}

interface ReadWriteDAO<K extends ReadWriteEntity, T extends ReadonlyEntity> extends ReadOnlyDAO<T> {
}

is this a good design?

3
  • 1
    This question cannot be answered without your actual interface names. Commented Oct 14, 2010 at 12:39
  • That's because generics are compile-time magic in Java (erasure), and therefore you cannot implement the same interface twice with different generic arguments. Commented Oct 14, 2010 at 12:56
  • @SLaks: please have a look at edited part. Commented Oct 14, 2010 at 14:05

6 Answers 6

5

I'd recommend thinking of a type for the Bar generic or rethink your design. If there's no object that makes sense for Bar, then it shouldn't be implementing Foo<T>.

EDIT:

is this a good design?

No, not in my opinion.

Sign up to request clarification or add additional context in comments.

Comments

3
interface Bar<T> extends Foo<T> {
    // code...
}

class BarImpl extends FooImpl implements Bar<Integer> {
    // code...
}

However, it would be best if we know the exact semantics of your interfaces.

Comments

2

The main problem is that you have the same interface used with two different generics; one with Integer and the other with the default Object.

The only solution is to have the exact same generic Integer.

You can do so by specifying directly interface Bar extends Foo<Integer> but if Bar isn't specifically related to a Foo<Integer> it doesn't make sense.

The other way is to generify Bar and use this generic to extend Foo :

interface Bar<T> extends Foo<T>{
    //...
}

Either way, as Bar is related to Foo; so either you specify the type for Foo in Bar (hardcode) or you must have a generic Bar.

Comments

0
interface Bar<T> extends Foo<T> {
 // code …
}

Is this what you are looking for? A Generic bar?

"Better Way" is kind of ambiguous.

Comments

0

"Integer type in Bar interface is totally useless. "

would indicate that Bar does not in fact extend Foo if the generic type is relevant there. More appropriate would be a base interface from which both Foo and Bar extend.

Comments

0

Integer type in Bar interface is totally useless.

I don't need T type in Bar.

This indicates that something is wrong on your design, there is no need for Bar to extend Foo. By the way what would fit perfect here is multi inheritance, but Java does not support it.

Following your example it should make more sense the following:

interface ReadOnlyEntity<T> {
 /* do something with generics */
 T read();
}

interface WriteOnlyEntity {
 /* do something without generics */
 void write();
}

class abstract BaseReadWriteEntity<T> implements ReadOnlyEntity<T>, WriteOnlyEntity {
}

interface ReadOnlyDAO<T extends ReadOnlyEntity> {
}

interface ReadWriteDAO<T extends BaseReadWriteEntity> extends ReadOnlyDAO<T> {
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.