3

我有以下代码:

public class AClass<X extends AnInterface> implements AnotherInterface {

    public AClass(X x){
    }

}

X当我可以将其替换为AnInterface??时,为什么要使用构造函数参数类型?当然,它们的意思是一样的,任何是AnInterface?的子类型。

我试图将我的所有参数类型保持为泛型,并且只在泛型参数声明中提及接口名称,例如“X 扩展 AnInterface”,但遇到问题,因为它表示我传入的 AnInterface 类型的值不相等键入 X。

编辑:

public void<X extends AnInterface> myMethod(){


    AnInterface b = new ADiffClass();
    AnotherInterface a = new AClass(b);
}

public class ADiffClass<X extends AnInterface> implements AnInterface {

    public ADiffClass(){
    }

}

这就是我遇到问题的地方,我收到一个编译错误,说 b 的类型是 AnInterface,而 AClass 的构造函数中所需的类型是 X。

4

5 回答 5

6

假设你有这种情况:

public class AClass<X extends AnInterface>{

    public AClass(X x){
        ...
    }

    public X getIt() {
        ...
    }

}

创建对象的人将有一个相应的接口,在这种情况下它会很有用。

例如:

// supposing DefaultAnInstance is an implementation of AnInstance interface
DefaultAnInterface obj = new DefaultAnInterface();
AClass<DefaultAnInterface> instance = new AClass<DefaultAnInterface>(obj);
...
// for the user getIt will return an objecct of type DefaultAnInterface
DefaultAnInterface obj = instance.getIt(); // there is no need to cast it to DefaultAnInterface
于 2012-07-11T13:24:21.293 回答
6

如果你声明一个这样的变量:

private AClass<Foo> a;

以下将是有效的:

 a = new AClass<Foo>(new Foo());

但以下不会:

 a = new AClass<Foo>(new Bar());

(假设FooBar是 的两个实现AnInterface)。

在这种情况下,这就是泛型的重点:将类型限制为实现(或扩展)AnInterface 的特定类型。

于 2012-07-11T13:24:31.210 回答
0

你为什么要扩展接口?你的意思是实现它?我认为问题在于您正在使用一个应该使用接口的类。如果您希望能够传入多个类中的某些内容,那正是接口的用途。

于 2012-07-11T13:23:26.037 回答
0

给定您的 AClass,您可能希望它比一般的泛型更通用 - 它不能处理任何类型,就像 LinkedList 这样的泛型可以,但您希望它能够处理很多类。

例如,假设您有一个类 SelfSortingList,它是通用的。它的所有对象都需要可比较才能进行排序。但是你不想让实现 Comparable 的 Widgets 和 Levers 在同一个列表中;那没有意义,他们对 Comparable 的特定实现可能反映了这一点。

所以你所做的就是说,“我希望我的 SelfSortingList 能够保存相同类型的对象,但它们必须是可比较的。” 这就是为什么您在类头 SelfSortingList 中同时具有类型参数 (X) 和 X 可以是什么(扩展 Comparable)的限制。

于 2012-07-11T13:43:57.907 回答
0

没有理由你不能。但是,这可能会破坏通用类的其余部分:

public class AClass<X extends AnInterface> {
    private X anInterface;
    public AClass(AnInterface anInterface) {
       // Not legal.  You'd have to narrow cast to X
       this.anInterface = anInterface;
    }
}

因此,您始终可以将“anInterface”的声明更改为 AnInterface 而不是 X。但是,泛型并没有给您任何东西,因为您不再指代 X

public class AClass<X extends AnInterface> {
    private AnInterface anInterface;
    public AClass(AnInterface anInterface) {
       // Not legal.  You'd have to narrow cast to X
       this.anInterface = anInterface;
    }
}

X有什么用?您将插入一个未使用的通用参数。

然后还有另一个答案中提到的构造函数类型安全问题。

这两个构造函数并不意味着同样的事情:

public AClass(AnInterface anInterface) { ... }
public AClass(X anInterface) { ... }

第一个意味着您可以拥有任何与 AnInterface 兼容的分配类(即实现或扩展它)。第二个意味着您可以拥有与提供的通用参数兼容的任何类,这可能比 AnInterface 更具体。有人在上面使用了这个例子:

public class Int1 implements AnInterface { ... }
public class Int2 implements AnInterface { ... }
public class Int3 extends Int1 { ... }

因此,如果您有:

AClass<Int1>  --> it could accept either Int1 or Int3, but not Int2 in the constructor
AClass<Int2>  --> it could accept only Int2 in the constructor
于 2012-07-11T14:50:09.940 回答