4

Enum と EnumMap をすべて含むクラスがたくさんあり、それらのクラスのスーパークラスを作成したい場合。

public interface ColorEnum {
}

class ColorMarbles extends Toy {
    enum MARBLE implements ColorEnum
        { BLUE, GREEN }
    EnumMap<MARBLE, String> names = new EnumMap<MARBLE, String>(MARBLE.class);
    //stuff
    // fields

    public void populate(ArrayList<String> designer) {
        int i = 0;
        for(MARBLE marble : MARBLE.values()) {
            marble.name = designer.get(i);
            i++;
        }
    }
}

class ColorBalloons extends Toy {
    enum BALLOON implements ColorEnum
        { YELLOW, RED }
    EnumMap<BALLOON, String> names = new EnumMap<BALLOON, String>(BALLOON.class);
    //stuff
    // fields

    public void populate(ArrayList<String> designer) {
        int i = 0;
        for(BALLOON balloon : BALLOON.values()) {
            balloon.name = designer.get(i);
            i++;
        }
    }
}

このような ColorEnum 型の列挙型を含む汎用 EnumMap を持つスーパークラスを作成するにはどうすればよいですか?

public abstract class Toy {
    EnumMap<ColorEnum, String> names;
}

eidt: 私の例が漠然としすぎていたことに気づきました。犬はおそらく悪い例です。できればもっと明確なものに変更します。

私が持っているのは、EnumMap を生成する populate のようなメソッドを持つ一連のクラスです。名前は事前定義された順序になっています。populate をすべてのクラスで定義する代わりに、Toy スーパークラスに持ち込めるようにしたいと考えているので、新しいクラス タイプの Toy ごとにコピー アンド ペーストを繰り返す必要はありません。

うまくいけば、これは私が探しているものをもっと説明します。

4

2 に答える 2

5

あなたのデザインは不必要に複雑すぎる気がします。

列挙型を使用

クラスの継承が必要ない場合は、最上位クラスと同じように列挙型を直接操作できます。

public interface Animal {}

public enum Dog implements Animal {
    HUSKY("Husky"), LAB("Labrador");

    private final String name;

    Dog(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

Enum は、フィールド、メソッドを宣言し、他の Java クラスと同様にインターフェイスを実装できます。唯一の制限は、直接のスーパークラスが常に存在java.lang.Enumし、拡張できないことです。

ただし、すべての列挙型定数は、コンストラクターに渡される独自の一意のデータ セットを持つことができます。各定数がその列挙型の共通メソッドを独自の実装でオーバーライドできる可能性さえあります。

列挙型の全機能について詳しく説明している素敵なチュートリアル: http://javarevisited.blogspot.cz/2011/08/enum-in-java-example-tutorial.html


列挙型なし

いくつかの一般的なメソッド (Animalスーパークラスなど) を共有するために実際のクラスの継承が必要な場合でも、マップ アプローチをやめて、より OOP 指向のものを試します。

public class Animal {
}

public abstract class Dog extends Animal {

    public abstract String getName();

    public static class Husky extends Dog {
        @Override
        public String getName() {
            return "husky";
        }
    }

    public static class Lab extends Dog {
        @Override
        public String getName() {
            return "labrador";
        }
    }

}
于 2013-02-20T16:21:04.327 に答える
3

Enumこのような目的で私が使用したメカニズムの 1 つは、詳細を渡すことができる汎用パラメーターを持つ汎用基本クラスを拡張することです。

この例では、Tableデータベース テーブルの基本クラスを定義します。

public class Table<Column extends Enum<? extends Column>> {
  // Name of the table.
  protected final String tableName;
  // All of the columns in the table. This is actually an EnumSet so very efficient.
  protected final Set<Column> columns;

  /**
   * The base interface for all Column enums.
   */
  public interface Columns {
    // What type does it have in the database?
    public Type getType();
  }

  // Small list of database types.
  public enum Type {
    String, Number, Date;
  }

  public Table(String tableName,
               Set<Column> columns) {
    this.tableName = tableName;
    this.columns = columns;
  }

}

これでサブクラス化できます:

public class VersionTable extends Table<VersionTable.Column> {

  public enum Column implements Table.Columns {
    Version(Table.Type.String),
    ReleaseDate(Table.Type.Date);

    // Sadly all of this must be in ALL of your enums but most of the work can be pushed up to `Table`
    final Table.Type type;

    Column(Table.Type type) {
      this.type = type;
    }

    @Override
    public Type getType() {
      return type;
    }
  }

  public VersionTable() {
    super("Versions", EnumSet.allOf(Column.class));
  }
}

列挙型を処理する親クラスの機能を利用します。

ここでEnumSetTableコンストラクターに を渡していることに注意してください。が不十分でEnumMapあると判断した場合は、要件に合わせてこれを変更できると確信しています。EnumSet

于 2013-02-20T16:39:08.233 に答える