我该怎么做呢? Java继承

时间:2016-05-17 20:58:20

标签: java class oop inheritance

我想要实现的目标有点复杂,特别是像我这样的人,但基本上,我会尽量解释它。

注意:不要担心封装,因为这只是一个原型。

我想要实现的是拥有一个扩展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);
}
}

2 个答案:

答案 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);
    }
}