我有2 个接口(interface):
public interface Flash { public void flash(int level); }
和
public interface SuperFlash extends Flash { public void flash(int level, boolean repeat); }
然后我有一个自定义集合类,它应该包含任意数量的实现 Flash
的东西或SuperFlash
。 类声明看起来像
public class FlashyThings<? extends Flash>
。
因此该类可以保存 Flash
类型的实例及其子类型。
类内FlashyThings
,我正在使用 ArrayList
容纳所有这些对象:
private ArrayList<? extends Flash> things;
到目前为止一切顺利,现在,当我尝试迭代集合时,有没有一种方法可以在不使用 instanceof
的情况下了解/推断对象的动态类型(如下一个片段所示)?
for (Flash f : this.things) {
if (f instanceof SuperFlash) { // <-- :(
// SuperFlash things
} else {
// Flash things
}
}
这是奖牌的上界,现在是下界
首先,我必须将类声明更改为
public class FlashyThings
因为类声明中不允许使用下限通配符。 ArrayList
声明现在看起来像:
private ArrayList<? super SuperFlash> things;
现在迭代集合变为:
for (Object o : this.things) { // <-- :((
// All things are of type Object which is *really* not cool
if (o instanceof SuperFlash) { // <-- :(
// SuperFlash things
} else {
// Flash things
}
}
所以我几乎陷入了困境。
迭代此类构造的推荐方法是什么?总而言之,我想要实现的是
- 最顶层描述的界面层次结构
- 类(class)
FlashyThings
可参数化 - 迭代
ArrayList things
,考虑到其内容的动态类型(无需执行instanceof
检查)
最佳答案
您需要做的是创建一个抽象的 FlashyThing,它在抽象类中执行尽可能多的共享方法,只将依赖于知道您拥有 Flash 或 SuperFlash 的内容留给子类。例如(为简洁起见,省略了公共(public)和私有(private)):
abstract class AbstractFlashyThing<F extends Flash> {
List<F> flashes;
AbstractFlashyThing() {
flashes = new ArrayList<F>();
}
void doOperations() {
for (F flash : flashes) {
doOperation(flash);
}
}
abstract void doOperation(F flash);
}
请注意泛型类型 F
如何尽可能用作占位符。
子类示例
class SuperFlashyThing extends AbstractFlashyThing<SuperFlash> {
@Override
void doOperation(SuperFlash superFlash) {
// do super flash stuff
}
}
子类是一个具体的实现,而不是泛型类,因此它的实例化如下。
SuperFlashyThing thing = new SuperFlashyThing();
// as opposed to the following
SuperFlashyThing<SuperFlash> thing = new SuperFlashyThing<SuperFlash>();
关于Java 泛型 - 使用上限和下限通配符进行迭代,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25547205/