mhshams
mhshams

Reputation: 16952

Java Generics and interfaces

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?

Upvotes: 4

Views: 5531

Answers (6)

mtrovo
mtrovo

Reputation: 879

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> {
}

Upvotes: 0

duffymo
duffymo

Reputation: 308743

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.

Upvotes: 5

jwenting
jwenting

Reputation: 5663

"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.

Upvotes: 0

Colin Hebert
Colin Hebert

Reputation: 93157

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.

Upvotes: 2

tylermac
tylermac

Reputation: 489

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

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

"Better Way" is kind of ambiguous.

Upvotes: 0

Bozho
Bozho

Reputation: 597036

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.

Upvotes: 3

Related Questions