简体   繁体   中英

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?

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.

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.

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 .

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

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

"Better Way" is kind of ambiguous.

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM