Java集合 – 对元素的多态访问
我有一个ThisH的LinkedHashSet值。 ThisType正在实现接口ThatType 。
我需要对此集合进行多态使用 – 能够将其指向LinkedHashSet 。
这是怎么做到的?
我知道这是一个天真的问题,但我试过的几件事情都行不通,我想以正确的方式去做。
提前致谢。
// ==============================
更新:更多细节:
在以下代码中, ThisType实现了ThatType – ThatType是一个接口。
//LinkedHashMap theMap = new LinkedHashMap(); LinkedHashMap 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 返回 。 我正在从LinkedHashMap转换为LinkedHashSet 。 但是,对于映射或集合中的集合值的多态引用没有任何作用。 到目前为止,我在所有这些操作中使用的所有类型都是ThisType 。 ThatType在我尝试过的任何地方给了我一些错误。
我想你想要的是使用通配符。
LinkedHashSet extends ThatType> someFunction(LinkedHashSet extends ThatType> set) { return set; }
正如其他地方所解释的, LinkedHashSet
不是LinkedHashSet
的子类,因为LinkedHashSet
不能接受ThatType
对象。
LinkedHashSet extends ThatType>
的通配符LinkedHashSet extends ThatType>
LinkedHashSet extends ThatType>
表示LinkedHashSet extends ThatType>
的某个类(不确定是什么)的ThatType
。
虽然你可能想考虑使用这个:
Set extends ThatType> someFunction(Set extends ThatType> set) { return set; }
当您声明通配符有界类型参数时
LinkedHashMap theMap = new LinkedHashMap<>();
您告诉编译器类型参数可以是作为ThatType
子类型的任何类。 想象一下这个案子
LinkedHashMap theMap = getLinkedHashMap();
其中getLinkedHashMap()
定义为
public LinkedHashMap getLinkedHashMap();
之前的赋值将起作用,因为OtherType
是OtherType
的子类型。 但是,你不能指望
ThisType a = theMap.get(key);
上class。 由于通配符,您只知道映射肯定包含ThatType
实例(称为上限 ),但它们可以是OtherType
或ThatType
类型(或ThatType
其他子类型)。 你最多可以做到
ThisType a = (ThisType) theMap.get(key);
转换返回值,但随后您将自己打开到ClassCastException
。
类似地,您不能使用除null
之外的任何内容调用put()
。
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 getTheSet(int[] intArray) { LinkedHashMap 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
是ThisType
的子类型, ThatType
可以将ThisType
实例放入地图中。 您需要注意如何使用此方法的返回值。 所有编译器都知道返回值是它包含ThatType
引用。 它不知道它们实际上是ThisType
。
你需要Set super ThisType>
的通配符Set super ThisType>
Set super ThisType>
。 请看下面的例子
public static void main(String[] args) { Set set=new LinkedHashSet<>(); Set set2=new LinkedHashSet<>(); someFunction(set); someFunction(set2); } static void someFunction(Set super ThisType> set) { } class ThisType implements ThatType{ } interface ThatType{ }