クラス内のすべてのメソッドが具体的であるときに、誰かがクラス抽象を宣言するための実用的なプログラミング状況はありますか?
9 に答える
テンプレートメソッドパターンを使用している可能性があります。このパターンでは、すべてデフォルトの実装を持つ複数のオーバーライドポイントがありますが、デフォルトの実装を組み合わせたもの自体は合法ではありません。機能的な実装はサブクラス化する必要があります。
(そして、はい、私はテンプレートメソッドパターンが嫌いです;))
抽象クラスは、抽象として宣言されたクラスです。抽象メソッドが含まれる場合と含まれない場合があります。それらはインスタンス化できないため、具象メソッドを持つ抽象クラスがある場合は、それをサブクラス化して、サブクラスをインスタンス化できます。
宣言されたメソッドが通常、実装時に同じデフォルトの動作を示すインターフェイスを想像してみてください。インターフェイスをサポートする必要があるクラスを作成するときは、デフォルトの動作を何度も定義する必要があります。
具象クラスの実装を容易にするために、各メソッドにデフォルトの動作を提供する抽象クラスを提供することができます。具象クラスでインターフェイスをサポートするには、抽象クラスから派生させ、メソッドが標準の動作から逸脱している場合はメソッドをオーバーライドします。そうすれば、同じ (冗長な) デフォルト動作の繰り返しの実装を避けることができます。
以前の回答はすでに主要な問題にぶつかっていますが、言及する価値のある小さな詳細があります。
抽象クラスの(隠された)サブクラスのインスタンスを返すファクトリを持つことができます。抽象クラスは、結果のオブジェクトのコントラクトを定義し、デフォルトの実装を提供しますが、クラスが抽象であるという事実は、クラスが直接インスタンス化されるのを防ぎ、「実際の」実装クラスのIDがそうではないという事実を示します。公開されました。
もう 1 つの考えられるユース ケースは、すべての呼び出しをラップされたインスタンスに委譲するデコレータです。具体的なデコレータの実装は、機能が追加されたメソッドのみをオーバーライドできます。
public interface Foo {
public void bar();
}
public abstract class FooDecorator implements Foo {
private final Foo wrapped;
public FooDecorator(Foo wrapped) { this.wrapped = wrapped; }
public void bar() { wrapped.bar(); }
}
public class TracingFoo extends FooDecorator {
//Omitting constructor code...
public void bar() {
log("Entering bar()");
super.bar();
log("Exiting bar()");
}
}
FooDecorator を抽象として宣言する必要性は実際にはわかりませんが (非抽象の例: HttpServletRequestWrapper )。
誰もMouseAdapterの実用例を指摘していないのはなぜだろうか:
http://docs.oracle.com/javase/6/docs/api/java/awt/event/MouseAdapter.html
マウス イベントを受信するための抽象アダプター クラス。このクラスのメソッドは空です。このクラスは、リスナー オブジェクトを作成するための利便性のために存在します。
いい質問:)
1つ確かなことは...これは確かに可能です。krosenvoldによるテンプレートの提案は、これを行う理由の1つです。
abstract
インスタンス化を防ぐためだけにクラスを宣言してはいけません。
これは、Java言語仕様セクション8.1.1.1で参照されています。