2016-05-17 23 views
-1

私が達成しようとしていることは、特に私のような人のために説明するのはちょっと複雑ですが、基本的にはできるだけ説明しようとします。これをどうやってやりますか? Java継承

注:これは単なるプロトタイプであるため、カプセル化は心配しないでください。

私が達成したいのは、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

ようこそ!私はあなたのコードに関連する部分を直接あなたの投稿に直接移動させました。これは、サイト外のコードがさまざまな理由でぶち壊されてしまうためです(他のサイトがダウンして、訪問者)。そうでなければ、問題と意図を明確に示すために、これはかなり良い質問でした。 – hexafraction

答えて

1

:後で

PersistenceData foo = new PlayerData("foo"); 

を、あなたは単にそれをキャストすることによってPlayerDataインスタンスとしてfooを使用することができます。

+2

「スーパークラスをサブクラスにキャストできません」という意味ではありませんか?サブクラスをそのスーパークラスにキャストすることが最も確実です。 – bhspencer

+0

ご返信ありがとうございます。問題は、そうするとPersistenceDataクラスにロードしたデータが失われることです。 PersistenceDataは、各Managerクラスに関する一般的なデータをロードするクラスですが、PlayerDataにはPersistenceData内のデータの情報が含まれています。また、Managerクラスを拡張しているPlayerManagerクラス内で処理されている情報もあります。 – TheAwesomeGem

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

私はすべてのメソッドを抽象的なにして、派生クラスに異なる実装を強制するようにします。つまり、 'Load(T data)'は 'PlayerManager'に対しては動作しますが、正しいデータは返されません。 –

+0

良い点があります。私はその問題を解決しました。 – TheAwesomeGem

関連する問題