我有 ThisType 的 LinkedHashSet 值。 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()&amp;上给出类型不匹配错误哈希的 get()方法。
不确定这是否重要 - 但是, 我将结果返回为 LinkedHashSet&lt; ThatType&gt; 。我正在从 LinkedHashMap 转换为 LinkedHashSet 。但是,对于映射或集合中的集合值的多态引用没有任何作用。到目前为止,我在所有这些操作中使用的所有和唯一类型是 ThisType 。 ThatType 在我尝试的任何地方都给了我一些错误。
答案 0 :(得分: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;
}
答案 1 :(得分: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
个实例(称为上限),但它们可以是OtherType
或{{1}类型}(或ThatType
的其他子类型)。你最多可以做到
ThatType
转换返回值,但随后您将自己打开ThisType a = (ThisType) theMap.get(key);
。
同样,您无法使用ClassCastException
以外的任何内容来呼叫put()
。
null
编译器不允许您添加任何内容,因为它无法保证地图包含的内容,因为通配符绑定。但是null
can be used because
null引用总是可以进行扩展引用转换 任何参考类型。
所以theMap.put(someInt, null); // will compile
theMap.put(someInt, new ThisType()); // will not compile
theMap.put(someInt, new OtherType()); // will not compile
是一个有效的参数,因为它是the lower bound of the wildcard。
您处于一种特殊情况,看起来您的方法会在内部创建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
。
答案 2 :(得分: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{
}