回顾性说明:这个问题的大部分都没有多大意义。这是我的第一个问题,并且充满了关于抽象类如何工作的错误假设。我不会删除它,因为可以从中学到一些东西,但我知道没有太多有用的信息可以从中提取。
我有一个名为Component ...的抽象基类
public abstract class Component
{
public abstract void doStuff();
}
我有一些Component的子类...
public class Camera extends Component
{
@Override
public void doStuff() {
//method specific to Camera objects
}
}
public class Transform extends Component
{
@Override
public void doStuff() {
//method specific to Transform objects
}
}
我需要一个方法可以迭代HashMap中的每个组件并调用相应的“doStuff();”每种方法。
我的第一个方法是做这样的事情......
public class Foo
{
HashMap<String, Component> components;
public Foo()
{
components = new HashMap<String, Component>();
components.put("Camera", new Camera());
components.put("Transform", new Transform());
}
public void bar()
{
//Assuming I don't know exactly what components are in the HashMap...
//Iterate through all components,
//Cast them to appropriate type,
//Call "doStuff();" in all components.
Iterator iterator = components.iterator();
while(iterator.hasNext())
{
Entry componentPair = (Entry) iterator.next();
Component component = (Component) componentPair.getValue();
component.doStuff();
}
}
}
但这段代码错了。 在上面的例子中,每次调用 component.doStuff(); 时,我都会在Component基类中调用空的doStuff方法。因此,没有子类 doStuff(); 方法实际上被称为。
请记住,我不想要向Component投射任何东西;我想将仅转换为Component的子类。
对于我的第二种方法,我尝试使用相关的字符串...
来转换组件...
while(iterator.hasNext());
{
Entry componentPair = (Entry) iterator.next();
String mapKey = componentPair.getKey().toString();
Object mapValue = componentPair.getValue();
Object component = Class.forName(mapKey).cast(mapValue);
component.doStuff();
}
...
但无法编译,因为组件被视为Object类型而 doStuff(); 不是Object类中的方法。
是否有解决此问题的方法不需要重新构建代码? 我可能非常糟糕地设计/构建了这个程序,因为我很确定使用Java无法进行动态转换。 如果是这样的话,有人能告诉我解决问题的好方法吗?也许使用接口代替?
答案 0 :(得分:0)
你的第一种方法是要走的路。
假设你有你描述的HashMap:
HashMap<String, Component> components = new HashMap<String, Component>();
components.put("Camera", new Camera());
components.put("Transform", new Transform());
如果需要键,可以迭代Map的EntrySet。如果您只想调用函数,可以使用map的value()函数。这样你也不需要迭代器结构,但你可以为每个循环使用a,在我看来这看起来更好。
for(Component nextComponent : components.values()){
// do some other stuff here
nextComponent.doStuff();
}
抽象方法不会被调用,你也不需要在这里投射任何东西,因为编译器已经知道要调用哪个函数。
答案 1 :(得分:0)
只要我记得,HashMap
没有iterator()
方法。
这种方法可以很好地工作,而不是entrySet
上的迭代器。
Iterator<Entry<String, Component>> iterator = components.entrySet().iterator();
while (iterator.hasNext()){
iterator.next().getValue().doStuff();
}
或者如果您只需要值
Iterator<Component> iterator = component.values().iterator();
while (iterator.hasNext()){
iterator.next().doStuff();
}
答案 2 :(得分:0)
在运行时,Component component
将是Camera
或Transform
的实例或Component
抽象类的任何其他实现。考虑到多态性(我建议你看一些关于它的文章,比如https://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html),将调用overriden doStuff()
方法。您不需要明确地将Component
实例投射到Camera
或Transform
,因此您的第一个示例就是可行的方法。
for (Component component : components.values()){
// component may be a Camera or Transform. It doens't matter; override will be called.
component.doStuff();
}