我想要实现的目标有点复杂,特别是像我这样的人,但基本上,我会尽量解释它。
注意:不要担心封装,因为这只是一个原型。
我想要实现的是拥有一个扩展PersistenceData类的类,以在扩展类中保存更多信息,并将其用于与PlayerManager类相对应的特定于此的类。虽然该代码会导致预期的错误:
Exception in thread "main" java.lang.ClassCastException: com.javatest.PersistenceData cannot be cast to com.javatest.PlayerData
所以我的问题是,我怎么能够实现这样的目标呢?我不知道这个模式叫什么,但也许有替代方案。
以下是我的数据类的层次结构:
public class PersistenceData
{
public String ID;
public String Name;
public PersistenceData(String id)
{
ID = id;
}
}
public class PlayerData extends PersistenceData
{
public int CharacterCount;
public PlayerData(String id)
{
super(id);
}
}
这是我的班级存储这些数据:
public abstract class Manager
{
protected final Map<String, PersistenceData> dataMap = new HashMap<>();
public void Load()
{
//Loading indefinite values from MYSQL here.
PersistenceData persistenceData = new PersistenceData("testid");
persistenceData.Name = "testname";
dataMap.put("testid", persistenceData);
}
public Map<String, PersistenceData> GetDataMap()
{
return dataMap;
}
public Map<String, PersistenceData> GetDataMapCopy()
{
return new HashMap<>(dataMap);
}
}
public class PlayerManager extends Manager
{
private static PlayerManager Instance;
public static PlayerManager GetInstance()
{
return Instance == null ? Instance = new PlayerManager() : Instance;
}
private PlayerManager()
{
}
@Override
public void Load()
{
super.Load();
PlayerData playerData = (PlayerData) dataMap.get("testid");
playerData.CharacterCount = 3;
System.out.println("ID: " + playerData.ID);
System.out.println("Name: " + playerData.Name);
System.out.println("Character Count: " + playerData.CharacterCount);
}
}
基本上,主要问题是,如何在不知道将要实例化哪种子类的情况下,基于超类实例化子类。我试图使用泛型,但似乎没有用。
public abstract class Manager <T extends PersistenceData>
{
protected final Map<String, T> dataMap = new HashMap<>();
public void Load()
{
//Loading indefinite values from MYSQL here.
T persistenceData = new T("testid");
// T extends from PersistenceData. So it needs to have a constructor of atleast 1 argument.
persistenceData.Name = "testname";
dataMap.put("testid", persistenceData);
}
public Map<String, T> GetDataMap()
{
return dataMap;
}
public Map<String, T> GetDataMapCopy()
{
return new HashMap<>(dataMap);
}
}
答案 0 :(得分:1)
您不能将子类实例强制转换为超类实例,但您可以执行以下操作:
PersistenceData foo = new PlayerData("foo");
稍后,您可以通过简单地投射foo
作为PlayerData
实例。
答案 1 :(得分:0)
好吧想通了。不确定它是否是最有效的方式,但它的工作原理。基本上我不得不推广Manager.java类,并使用PlayerManager.java上的子类来完成这项工作。可能有更好的方法来做到这一点,我不知道。
Manager.java
public abstract class Manager <T extends PersistenceData>
{
protected final Map<String, T> dataMap = new HashMap<>();
public void Load(T data)
{
data.Name = "TestName";
dataMap.put(data.ID, data);
}
public Map<String, T> GetDataMap()
{
return dataMap;
}
public Map<String, T> GetDataMapCopy()
{
return new HashMap<>(dataMap);
}
}
PlayerManager.java
public class PlayerManager extends Manager<PlayerData>
{
private static PlayerManager Instance;
public static PlayerManager GetInstance()
{
return Instance == null ? Instance = new PlayerManager() : Instance;
}
private PlayerManager()
{
}
public void Load()
{
PlayerData playerData = new PlayerData("testid");
super.Load(playerData);
playerData.CharacterCount = 3;
System.out.println("ID: " + playerData.ID);
System.out.println("Name: " + playerData.Name);
System.out.println("Character Count: " + playerData.CharacterCount);
}
}