2017-02-11 20 views
1

私はプレイヤーがプレイするためのカスタムアリーナを作成できるオンラインアリーナゲームを作成しようとしています。私は、アリーナの設定をMySQLデータベースに保存して、プレイするためのアリーナを保存したいと考えています。ジェネリックマネージャクラスから、静的な方法でインスタンスの情報にアクセスする方法は?

キャッチは、アリーナのさまざまなバリエーションがあります。ジャングルアリーナ、砂漠のものなどがあります。これらのさまざまなバリエーション(抽象クラ​​スArenaのサブクラス)は、変数(したがって列)がアリーナのタイプごとに異なるため、異なるテーブルに格納する必要があります。

私の質問は、下記のジェネリックタイプの配列を含むManagerクラスから、どのようにして子(T)クラスとその親から必要な列を取得できるかです。私はジェネリック型を使用しています。なぜなら、このクラスを後で(データベースに保存する必要がある)プレーヤの情報を管理するために使用したいからです。ここで

は、マネージャークラスである:ここで

public class Manager<T extends Savable> { 
    private Connection connection; 
    private List<Column<?>> columns; 

    private List<T> instances; 

    public Manager() { 
    fillColumnArray() 

    try { 
     connection = getSQLConnection(); 
     Statement s = connection.createStatement(); 
     s.executeUpdate(getCreateQuery()) 
     s.close(); 

    } catch (SQLException e) { 
     e.printStackTrace(); 
    } 
    } 

    public void fillColumnArray() { 
    // Somehow, manages to get the needed columns from 
    // the parent class and the child class 
    } 

    public Connection getSQLConnection() { 
    // Creates a mysql connection to a database 
    // from parameters on a local file and returns it 
    } 

    public String getCreateQuery() { 
    // Creates the query from the previously found columns 
    } 

    /* */ 
} 

はマネージャーで使用される列クラスです:

public class Column<U> { 
    private String name; 
    private U defaultValue; 

    /* */ 
} 

そしてここでは、アリーナクラスのための可能な変数と一つの可能​​な子供

です
public abstract class Arena implements Savable { 
    private Vector centerPosition; 
    private int radius; 
    private int gameLenght; 

    /* */ 
} 

public class JungleArena extends Arena { 
    private int treeHeight; 
    private boolean daytime; 

    /* */ 
} 

私はさまざまな可能性を考えました。そのうちの1つはSavableインターフェイスにrequestColumns()メソッドを追加することでしたが、このオプションは機能しません。これはManagerの作成時に静的な方法でTクラスにしかアクセスできないためです。

したがって、私は子供と親の両方で静的メソッドrequestColumns()を追加することを考えましたが、ジェネリック型を使用しているので、コンパイラはメソッドがどこから来るのか理解できませんでした。

次に、私はT型をspecefic Arena型にキャストしようと考えましたが、プレーヤを格納するために同じクラスを使用すると、私のプロジェクトではそれ以上は機能しません。

希望はこれで十分です。

誰かが、物事を働かせるためのアイデアを持っているか、あるいはあなたの理解から物事を行う別の方法はありますか?あなたはすでにインスタンスを持って考えると、静的にこれを実行する必要があるでしょうし、あなたが一般的な方法であなたのために、この情報を取得するには、インスタンスを使用することができますなぜ

おかげで

+0

は、念のために、あなたが救うためにどのようなテーブルマネージャを伝えるためにどのように迷っているの'Arena'のクラスにしたがって値を設定しますか? – MikaelF

+0

さて、テーブルにどのような値が入るかマネージャに伝えたい –

+0

"instanceof"演算子を使ってクラスの内容を確認できますか? – MikaelF

答えて

0

私はわかりません。また、クラスから列の値を取得する方法を明確にしていませんが、この回答は、まだ入力していない場合はそれを処理します。

個人的には、これが可能な任意の価値のあるフレームワークがないと、列フィールドのパブリックゲッターを置くアノテーションを定義します。同様に、

@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.METHOD) 
public @interface Column { 
    String name() default ""; 
} 

リフレクションを使用してこれらのゲッターを取得し、インスタンスのメソッドを呼び出して値を取得することもできます。たとえば、このクラスを与えられた:

class Entity { 
    ... 

    @Column(name = "Name") 
    public getName() { return name; } 

    @Column(name = "Height") 
    public getHeight() { return height; } 
} 

私はそうのようなカラム名と値を得ることができます:

Entity e = new Entity("First", 42); 
    Method[] methods = e.getClass().getMethods(); 
    Map<String, Method> colums = new HashMap<>(); 
    for (Method m : methods) { 
     Column c = m.getAnnotation(Column.class); 
     if (c != null) { 
      colums.put(c.name(), m); 
     } 
    } 
    colums.entrySet().forEach(entry -> { 
     try { 
      System.out.println(entry.getKey() + ": " + entry.getValue().invoke(e)); 
     } catch (IllegalAccessException | InvocationTargetException e1) { 
      e1.printStackTrace(); 
     } 
    }); 


Output > 
Height: 42 
Name: First 
関連する問題