我有一个 ArrayList,其中包含不同类的一些实例,我想在 for 循环中迭代特定类型的类(例如扩展 OnRender.class 的类); 我有一个工作代码,但该代码违反了 OO 规则,导致出现一些警告。 我可以做到这一点吗?否则我将永远因沮丧而打破 OO。
回顾我写的内容,我发现我没有很好地解释它,所以请检查下面的代码以了解我的意思
代码:
public class ListenerManager{
List<Object> listeners=new ArrayList<Object>();
int it;
Class clazz;
public <T extends Object> T begin(Class<T> clazz){
it=-1;
this.clazz=clazz;
return next();
}
public <T extends Object> T next(){
while((++it)<listeners.size()){
if (clazz.isInstance(listeners.get(it))){
return (T)listeners.get(it);
}
}
return null;
}
public void add(Object listener){
listeners.add(listener);
}
}
我就是这样使用的:
ListenerManager lm=new ListenerManager();
lm.add(new OnRenderListener(){
........
});
for(OnRenderListener orl=lm.begin(OnRenderListener.class);orl!=null;orl=lm.next){
.......
}
我收到的警告:
Class clazz;
-> 类是原始类型。对泛型类型 Class 的引用应该参数化
return (T)listeners.get(it);
-> 类型安全:从对象到 T 的未经检查的强制转换
我不想仅使用 Suspecnd 注释来暂停警告,我想遵循 OO 规则。
最佳答案
如果您想标识特定的类或接口(interface),请使用instanceof:
for (Object o : listeners) {
if (o instanceof X) {
X x = (X)o;
}
}
但是这根本不是很好。您确实想利用该语言的继承和多态性。我的第一个想法是您的列表应该仅包含 Listeners
或子类型,例如
listeners = new ArrayList<Listener>();
然后你就不需要类型转换了。您从列表中取出的所有内容都将是监听器(或子类型)并键入如下:
for (Listener l : listeners) {
// listener type functionality here...
}
Visitor pattern这里也是一个选项。您可以将访问者对象传递给每个监听器,每个监听器将根据其类型决定要执行的操作。优点是,当您添加子类型时,您必须添加适当的方法 - 不存在从类声明序列中省略类型的危险。
Visitor v = new OnlyInterestedInOneTypeOfListener();
for (Listener l : listeners) {
l.useVisitor(v); // different subclasses will call different methods
// on the visitor. Some may be no-ops for different visitor
// implementations
}
(顺便说一句,我注意到您想要发现实现特定方法的条目。这称为 duck-typing ,Java 不支持它。其他语言(例如 Scala)支持)
关于java - 迭代列表中的特定实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24676174/