Java泛型和接口

4
拥有这个设计:
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和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> {
}

这是一个好的设计吗?

1
无法回答此问题,需要提供您的实际接口名称。 - SLaks
这是因为 Java 中的泛型是编译时魔法(类型擦除),因此您不能使用不同的泛型参数两次实现相同的接口。 - Lucero
@SLaks:请看一下编辑部分。 - mhshams
6个回答

5

我建议您考虑一个适用于泛型Bar的类型或重新设计。如果没有任何与Bar相关的对象,则不应该实现Foo<T>

编辑:

这是一个好的设计吗?

不,我认为不是一个好的设计。


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

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

然而,如果我们知道你的接口的确切语义将会更好。


2

主要问题在于你有两个不同的泛型使用了相同的接口;一个是用 Integer,另一个是用默认的 Object

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

您可以通过直接指定 interface Bar extends Foo<Integer> 来实现,但如果 Bar 没有特定地与 Foo<Integer> 相关联,那么这样做就没有意义。

另一种方法是将 Bar 泛型化,并使用该泛型扩展 Foo

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

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

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

这是您要找的吗?一个通用的条形图?

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


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

0
"Bar接口中的整数类型完全没有用处。" 这表明如果泛型在那里是相关的,那么Bar实际上并没有扩展Foo。更合适的做法是创建一个基础接口,让Foo和Bar都扩展它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接