Java泛型和接口

时间:2010-10-14 12:38:38

标签: java generics

有这样的设计:

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

它给我编译错误:

  

接口Foo不能   实施不止一次   不同的论点:Foo和   富

对此问题的一个简单修复是:

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

Bar界面中的整数类型完全没用。

有没有更好的方法来解决这个问题? 任何更好的设计?

感谢您的建议。

修改

给出解决方案:

> interface Bar<T> extends Foo<T> 

没问题,但与我之前的解决方案相同。我在Bar中不需要T型。

让我给出一个更好的样本:

interface ReadOnlyEntity {
}

interface ReadWriteEntity extends ReadOnlyEntity {
}

interface ReadOnlyDAO<T extends ReadOnlyEntity> {
}

interface ReadWriteDAO<K extends ReadWriteEntity, T extends ReadonlyEntity> extends ReadOnlyDAO<T> {
}
这是一个很好的设计吗?

6 个答案:

答案 0 :(得分:5)

我建议考虑Bar generic的类型或重新考虑你的设计。如果没有对Bar有意义的对象,则不应该实现Foo<T>

编辑:

  

这是一个很好的设计吗?

不,不在我看来。

答案 1 :(得分:3)

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

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

但是,如果我们知道接口的确切语义,那将是最好的。

答案 2 :(得分:2)

主要问题是你有两个不同的泛型使用相同的界面;一个使用Integer,另一个使用默认Object

唯一的解决方案是使用完全相同的通用Integer

您可以直接指定interface Bar extends Foo<Integer>来执行此操作,但如果BarFoo<Integer>没有特别关联,那么它就没有意义。

另一种方法是生成Bar并使用此通用扩展Foo

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

无论哪种方式,因为BarFoo相关;因此,要么在Foo(硬编码)中指定Bar的类型,要么必须具有通用Bar

答案 3 :(得分:0)

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

这是你在找什么?通用栏?

“更好的方式”有点含糊不清。

答案 4 :(得分:0)

  

“Bar接口中的整数类型是   完全没用。 “

表示如果泛型类型与那里相关,Bar实际上并不扩展Foo。 更合适的是Foo和Bar扩展的基本接口。

答案 5 :(得分:0)

  

Bar接口中的整数类型是   完全没用。

     

Bar中我不需要T型。

这表明你的设计出了问题,Bar不需要扩展Foo。顺便说一句,这里完美的是多继承,但Java不支持它。

按照你的例子,它应该更有意义:

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