![](/img/trans.png)
[英]Is it possible to load the contents of a single class file into an Object, and cast it into a spicific type?
[英]Is it possible to cast an Object using the contents of a String?
回顧性注釋:這個問題大部分都沒有多大意義。 這是我的第一個問題,充滿了關於抽象類如何工作的錯誤假設。 我不會刪除它,因為可能會從中學到一些東西,但是我知道並沒有很多有用的信息可以提取。
我有一個名為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的子類 。
對於第二種方法,我嘗試使用相關的String強制轉換組件。
...
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無法實現動態轉換。 如果是這樣,有人可以告訴我解決問題的好方法嗎? 也許改為使用接口?
您的第一種方法是要走的路。
假設您具有描述的HashMap:
HashMap<String, Component> components = new HashMap<String, Component>();
components.put("Camera", new Camera());
components.put("Transform", new Transform());
如果需要鍵,則可以遍歷Map的EntrySet。 如果只想調用函數,則可以使用地圖的values()函數。 這樣,您也不需要迭代器結構,但是可以為每個循環使用a,在我看來看起來更好。
for(Component nextComponent : components.values()){
// do some other stuff here
nextComponent.doStuff();
}
不會調用abstract方法,並且您也不需要在此處強制轉換任何東西,因為編譯器已經知道要調用哪個函數。
只要我記得, 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();
}
在運行時, Component component
將是Camera
或Transform
的實例或Component
抽象類的任何其他實現。 考慮到多態性(我建議您看一些有關它的文章,例如https://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html ),將調用重寫的doStuff()
方法。 您無需將Component
實例顯式Transform
為Camera
或Transform
,因此您的第一個示例就是方法。
for (Component component : components.values()){
// component may be a Camera or Transform. It doens't matter; override will be called.
component.doStuff();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.