私は現在Javaでゲームのコードを書いています(ここでは初心者プログラマーです)が、危険性や利点がわからない、または表示モードを初期化し、キーリスナーを実装するゲームループに入る抽象クラスを 持つ必要がある場合はわかりませんコントロール用
3 に答える
Abstract Class
Interface
との間ですBaseClass
。つまり、実装されているメソッドと実装されていないメソッドがある場合があります。
共通の実装を持つサブクラスのすべてのメソッドは、Abstract クラス自体で実装できます。
あなたのListener
実装が抽象クラスの実装クラスのほとんどに共通していると思われる場合は、抽象クラスでリスナーを定義してもまったく問題ないと思います。実装が同じではなく、ほとんどの実装クラスで同じメソッドが必要な場合は、署名を抽象クラスの抽象メソッドとして定義します。共通点がないなら、抽象クラスには入れないほうがいいと思います。
リスナーに抽象クラスよりもインターフェイスを優先する理由は 2 つあります (私が考えることができます)。
すべてが抽象化されている複数のリスナーがある場合、クラスが複数のリスナーを実装することが理にかなっている場合でも、クラスは 1 つのリスナーからしか継承できません。
すでに別のクラスから継承している既存のクラスがあるかもしれませんが、それをリスナーとしてマークすることもできます。
インターフェイスを使用することに決めたが、共通の実装を共有したい場合、これを達成するためのパターンは、リスナー インターフェイスと抽象実装の両方を作成することです。
interface ClickListener {
void onLeftClickPressed();
void onLeftClickReleased();
}
// "DefaultClickListener" and "AbstractClickListener" are also common conventions
abstract class DoubleClickListener implements ClickListener {
int leftClickCount;
@Override public final void onLeftClickPressed() {
++leftClickCount;
if (leftClickCount == 2) {
onDoubleClicked();
}
}
@Override public final void onLeftClickReleased() { --leftClickCount; }
protected abstract void onDoubleClicked();
}
リスナー インターフェイスに複数のメソッドがある場合は、それらすべてにスタブ化された実装を提供するアダプター バージョンを提供すると便利です。
interface ComplexListener {
void onEvent1();
...
void onEvent100();
}
abstract class ComplexListenerAdapter implements ComplexListener {
@Override public void onEvent1() {}
...
@Override public void onEvent100() {}
}
final class MySimpleListener extends ComplexListenerAdapter {
// The only event I care about
@Override public void onEvent42() { ... }
}
それが標準的な規則かどうかはわかりませんがListenerAdapter
、この種のリスナーの実装に使用される名前を見てきました。