我该怎么做呢? Java继承

时间:2021-08-25 11:12:37

What I am trying to achieve is a bit complicated to explain especially for a person like me but basically, I will try to explain it as much as I can.

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

Note: Don't worry about the encapsulation since this is just a prototype.

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

What I want to achieve is having a class that extends the PersistenceData class to hold more information in the extended class and use it in corresponding to the PlayerManager class as it's specific to that. Although that code results in an expected error:

我想要实现的是有一个类扩展PersistenceData类以在扩展类中保存更多信息,并将其用于对应于PlayerManager类,因为它是特定于此的。虽然该代码导致预期的错误:

Exception in thread "main" java.lang.ClassCastException: com.javatest.PersistenceData cannot be cast to com.javatest.PlayerData

So my question is, how would I be able to achieve something like this? I don't know what this pattern is called but perhaps there is an alternative to this.

所以我的问题是,我怎么能够实现这样的目标?我不知道这个模式叫什么,但也许有一个替代方案。

Here is the hierarchy of my data classes:

这是我的数据类的层次结构:

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

And here is my class that stores these pieces of data:

这是我的类存储这些数据:

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

Basically the main question is, how do I instantiate a subclass based on the superclass without knowing what kind of subclass is going to be instantiated. I tried to use generics but doesn't seem to work.

基本上主要的问题是,如何在不知道将要实例化哪种子类的情况下,基于超类实例化子类。我试图使用泛型,但似乎没有用。

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 个解决方案

#1


1  

You can't cast a subclass instance to a superclass instance, but you can do something like this:

您不能将子类实例强制转换为超类实例,但您可以执行以下操作:

PersistenceData foo = new PlayerData("foo");

Later on, you can use foo as a PlayerData instance by simply casting it.

稍后,您可以通过简单地投射它来将foo用作PlayerData实例。

#2


0  

Alright figured it out. Not sure if it's the most efficient way but it works. Basically I had to generalized the Manager.java class and I use the subclass on the PlayerManager.java to make this work. There is probably better ways to do this that I am not aware of.

好吧想通了。不确定它是否是最有效的方式,但它的工作原理。基本上我不得不概括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);
    }
}

#1


1  

You can't cast a subclass instance to a superclass instance, but you can do something like this:

您不能将子类实例强制转换为超类实例,但您可以执行以下操作:

PersistenceData foo = new PlayerData("foo");

Later on, you can use foo as a PlayerData instance by simply casting it.

稍后,您可以通过简单地投射它来将foo用作PlayerData实例。

#2


0  

Alright figured it out. Not sure if it's the most efficient way but it works. Basically I had to generalized the Manager.java class and I use the subclass on the PlayerManager.java to make this work. There is probably better ways to do this that I am not aware of.

好吧想通了。不确定它是否是最有效的方式,但它的工作原理。基本上我不得不概括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);
    }
}