私はゲームでプログラムしたいと思う2つのクラスApple
とLemon
があります。 draw(Graphics g)
とsetColor(Color color)
のような多くの機能が2つのクラスで共有されています。サブクラスが強制的にenumを宣言し、それを抽象的な方法でスーパークラスから参照する方法はありますか?
public class Apple {
public enum Color {
Red, Green;
}
private Color color;
private Sprite[] sprites;
public Apple() {
color = Color.Red;
sprites = loadSprites("apple.png"); // [0]=redSprite, [1]=greenSprite
}
public void setColor(Color color) {
this.color = color;
}
public void draw(Graphics g) {
sprite[color.ordinal()].draw(g);
}
}
public class Lemon {
public enum Color {
Yellow, Green;
}
private Color color;
private Sprite[] sprites;
public Lemon() {
color = Color.Yellow;
sprites = loadSprites("lemon.png"); // [0]=yellowSprite, [1]=greenSprite
}
public void setColor(Color color) {
this.color = color;
}
public void draw(Graphics g) {
sprite[color.ordinal()].draw(g);
}
}
両方がFruit
であり、同様の機能を共有するので、私はスーパークラス内にできるだけ多くの仕事を拡張し、強制することの両方のためにabstract
スーパークラスを作成します。
public abstract class Fruit {
private Sprite[] sprites;
private Color color;
protected Fruit(String filepath, Color colorDefault) {
sprites = loadSprites(filepath);
color = colorDefault;
}
public void setColor(Color color) {
this.color = color;
}
public void draw(Graphics g) {
sprites[color.ordinal()].draw(g);
}
}
public class Apple {
public enum Color {
Red, Green;
}
public Apple() {
super("apple.png", Color.Red);
}
}
public class Lemon {
public enum Color {
Yellow, Green;
}
public Lemon() {
super("lemon.png", Color.Yellow);
}
}
残念ながら、2つの別個のカラー列挙があるため、残念ながら、これはうまくいきません。共有Color
列挙型を作成できますが、両方のケースで無効な色が渡され、特定のサブクラスの順序では不可能になります(つまり、緑色がリンゴで1番目、レモンで2番目の場合)。
public enum Color { // this seems hacky
Green(2), // Valid for both
Red(1), // Only valid for apple
yellow(1); // Only valid for lemon
private int position;
public Color(int position) {
this.position = position;
}
@Override
public int ordinal() {
return position;
}
}
似たようなインターフェイスを共有しようとしましたが、お互いの無効な色を渡すことができます。
理想的には、サブクラス自身が有効な列挙型の値を宣言し、Color
列挙型を宣言することが理想です。列挙型をabstract
に設定すると動作するはずですが、javaでは許可されていないようです。
public abstract class Fruit {
private Sprite[] sprites;
private Color color;
public abstract enum Color; // not allowed
protected Fruit(String filepath, Color colorDefault) {
sprites = loadSprites(filepath);
color = colorDefault;
}
public void setColor(Color color) {
this.color = color;
}
}
私はスーパークラスでセッターを維持しながら、そのように、これらのオブジェクトを作成して設定することができるようにしたいです。
Apple apple = new Apple();
apple.setColor(Apple.Color.Green);
Lemon lemon = new Lemon();
lemon.setColor(Lemon.Color.Yellow);
これを実行する方法はありますか、私はsetColor(Color color)
メソッドを書き換えて、私のFruit
サブクラスのすべてでColor
列挙型を追加することを忘れないことを余儀なくですか?
TL; DR私はスーパークラスにクラス固有の列挙型のパラメータを持つ関数を移動し、列挙型を定義するには、サブクラスを強制したい 。 Javaでこれを実現することは可能ですか?それとも、すべてのサブクラスで自分自身を覚えなくてはなりませんか?
'Apple'と' Lemon'は実際に別のクラスではありません。人間には違いますが、実際には 'DrawableObject'や' Sprite'のインスタンス、あるいはあなたが呼ぶものは何でも構いません。 – Kayaman
'enum'は'抽象化 'できません - それは、各要素がそのクラスのインスタンスである特別な種類の具象クラスとして見ることができます。あなたができることは、あなたの 'enum'によって実装された' Color'インターフェースを持っていて、あなたは 'Color'のために持っている契約をこのインターフェースで定義することができます。そのようなインターフェースを 'Color' enumから抽出できない場合は、Enumと' Apple'と 'Lemon'の両方が共有する' Color'エンティティとの間にIS-A関係がないことを意味します。 –