0

我有一个LinkedHashSetThisType值。 ThisType正在实现接口ThatType

我需要这个集合的多态使用——能够将它指向为LinkedHashSet< ThatType >。

这是怎么做到的?

我知道这是一个幼稚的问题,但我尝试过的几件事没有奏效,我想以正确的方式去做。

提前致谢。

//================================

更新:更多细节:

在下面的代码中,ThisType实现了 ThatType —— ThatType是一个接口。

//LinkedHashMap<Integer, ? extends ThatType> theMap = new LinkedHashMap<>();
LinkedHashMap<Integer, ThisType> theMap = new LinkedHashMap<>();
for (Integer key:intArray)  {
    ThisType a = new ThisType();
    if (theMap.containsKey(key))  {
        a = theMap.get(key);    
        a.doStuff();
    } else {
        a.doOtherStuff();
    }
    theMap.put(key, a);
}

最后,我想将theMap作为ThatType ** 的集合返回,而不是 **ThisType

这就是链条断裂的地方。使用注释行(第一行)进行声明会在散列的put()get()方法上出现类型不匹配错误。

不确定这是否重要——但是,我将结果返回为LinkedHashSet< ThatType >。我正在进行从LinkedHashMapLinkedHashSet的转换。但是,对于映射或集合中的集合值的多态引用,没有任何效果。到目前为止,我在所有这些操作中使用的所有且唯一的类型是ThisTypeThatType几乎在我尝试过的任何地方都给了我一些错误。

4

3 回答 3

2

我认为您想要的是使用通配符。

 LinkedHashSet<? extends ThatType> someFunction(LinkedHashSet<? extends ThatType> set) {
      return set;
 }

正如在别处解释的那样LinkedHashSet<ThisType>,它不是 的子类LinkedHashSet<ThatType>,因为LinkedHashSet<ThisType>不能接受ThatType对象。

通配符LinkedHashSet<? extends ThatType>表示LinkedHastSet扩展的某个类(不确定是什么)ThatType

尽管您可能需要考虑使用它:

 Set<? extends ThatType> someFunction(Set<? extends ThatType> set) {
      return set;
 }
于 2013-11-13T05:47:27.523 回答
1

当您声明通配符有界类型参数时

LinkedHashMap<Integer, ? extends ThatType> theMap = new LinkedHashMap<>();

您是在告诉编译器类型参数可以是任何属于ThatType. 想象一下这个案例

LinkedHashMap<Integer, ? extends ThatType> theMap = getLinkedHashMap();

其中getLinkedHashMap()定义为

public LinkedHashMap<Integer, OtherType /* which implements ThatType */> getLinkedHashMap();

之前的分配会起作用,因为OtherType它是ThatType. 然而,你无法期待

ThisType a = theMap.get(key);

去工作。由于通配符,您所知道的是地图肯定包含 ThatType实例(称为上限),但它们可能是类型OtherTypeThatType(或其他子类型ThatType)。最多你可以做

ThisType a = (ThisType) theMap.get(key);

投射返回值,但随后您将自己开放给ClassCastException.

同样,您不能put()使用除 之外的任何内容进行调用null

theMap.put(someInt, null); // will compile
theMap.put(someInt, new ThisType()); // will not compile
theMap.put(someInt, new OtherType()); // will not compile

编译器不允许您添加任何内容,因为它不能保证地图包含的内容,同样是因为通配符绑定。但是null可以使用,因为

空引用始终可以进行扩展引用转换为任何引用类型。

一个有效的参数也是如此null,因为它是通配符下限


您处于一种特殊情况,您的方法似乎在LinkedHashMap内部创建并且您知道将传递给它的内容。因此,您可以执行以下操作

public static LinkedHashMap<Integer, ThatType> getTheSet(int[] intArray) {
    LinkedHashMap<Integer, ThatType> theMap = new LinkedHashMap<>();

    for (Integer key : intArray) {
        ThisType a = new ThisType();
        if (theMap.containsKey(key)) {
            a = (ThisType) theMap.get(key); // cast it because you know they will definitely be `ThisType` references
            a.doStuff();
        } else {
            a.doOtherStuff();
        }
        theMap.put(key, a);
    }

    return theMap;
}

由于ThisType是 的子类型ThatType,因此您可以将 的实例ThisType放入地图中。您需要注意如何使用此方法的返回值。编译器只知道返回值包含ThatType引用。它不知道它们实际上是ThisType.

于 2013-11-13T15:00:44.917 回答
0

您需要Set<? super ThisType>. 看下面的例子

public static void main(String[] args) {
    Set<ThatType> set=new LinkedHashSet<>();
    Set<ThisType> set2=new LinkedHashSet<>();

    someFunction(set);
    someFunction(set2);
}

static void someFunction(Set<? super ThisType> set) {

}

class ThisType implements ThatType{

}
interface ThatType{

}
于 2013-11-13T05:53:06.740 回答