質問のタイトルはそれを要約していると思います。ABCがデータメンバーを持つことは良い設計であると考えられる時期はありますか?これで大丈夫な状況があるのではないかと思っていました。私が思いつくことができるのは静的なものだけであり、それでもそれは一種のストレッチです。
9 に答える
ABCがサブクラスに提供するメソッドをサポートするために必要な、インスタンスごとの(非静的)データメンバーを適切に持つことができなかった理由がわかりません。テンプレートメソッドDP(フックメソッドは抽象的)を提供するためにABCが存在する一般的なケースを考えてみましょう。組織化メソッドの機能の一部が、いくつかのインスタンス変数を更新することである場合(たとえば、メソッドが呼び出されました)、明らかにそれらの変数もABCによって提供される必要があります。それが悪いデザインだと思う理由をもっとよく説明できますか?!
抽象クラスは、それを継承するクラスに提供する機能をサポートするために必要なメンバーを持つことができます。これらがサブクラスから直接アクセスできるとは限りません。これらは、サブクラスまたはそのクライアントによって行われるメソッド呼び出しによってのみ読み取られ、変更される場合があります。
これは、Paint.NETのようなプラグインアーキテクチャで見られます。
制御の反転にはこれが必要な場合があります。たとえば、Loggerのインスタンスを取得するクラスがたくさんある場合、それらのベースとなる抽象クラスには、コンストラクターがそれをメンバー変数またはプライベートプロパティに格納する可能性があります(もちろん、ベースコンストラクターをgrinと呼ぶことを忘れないでください) 。
抽象クラスのデータメンバーにクラスを継承するための基本コードが含まれている場合は問題ありません
データメンバーがクラスを説明するだけの場合、インターフェイスの使用について考えます
他の人が述べたように、状態を保存する必要がある場合は、あらゆる種類のクラスにインスタンス フィールドを追加します。これは、抽象クラスまたは具象クラスに当てはまります - 違いはありません。
なぜそれが違いを生む必要があるのですか?結局のところ、抽象クラスは、クラスを完成させるためにサブクラス化などが必要であり、インスタンス化できないことを除いて、すべてのクラスと同じです。
継承されたすべてのクラスで使用される状態である場合は、基本クラスに移動することが必須であると思います。ベースは抽象的ですが。リファクタリングに興味のあるほとんどの人は、これについて私に同意すると思います。
一部の状態がベースにある必要がある理由はいくつか考えられます。コードの重複を減らすことは十分な理由です。
乾杯 !
編集:改善できるように、反対票を投じる理由を教えてください。ありがとう!
はい、サブクラスがそれらのメンバーを使用して具体的な実装を行うことを意図して、抽象基本クラスにメンバー変数を提供することは可能です。
これは、私たち全員が愛するようになった車のアナロジーを使用した具体的な例です。
Car
サブクラスが使用するホイール、シャーシ、およびエンジンのプレースホルダーを持つ抽象基本クラスを作成するとします。
abstract class Car {
Wheels wheels
Chassis chassis
Engine engine
abstract void accelerate();
abstract void decelerate();
}
を拡張するクラスCar
の場合、メンバーは使用するために既にそこにあるため、サブクラスの役割はこれらのメンバー変数を設定することです。
class NiceCar extends Car {
Decoration decoration;
public NiceCar() {
wheels = new ChromeWheels();
chassis = new LightweightCompositeChassis();
engine = new LotsOfHorsepowerEngine();
decoration = new CoolRacingStripes();
}
void accelerate() {
engine.feedFuel();
}
void decelerate() {
wheels.applyBrakes();
}
}
ご覧のとおり、抽象基本クラスは、クラスの完全な機能を得るためにコンポーネント (メンバー変数) を入力する必要がある青写真として機能します。この場合、 はCar
、具体的な実装で使用される車の基本パーツを提供します。NiceCar
これらのメンバー フィールドを使用し、装飾的なペイント ジョブなどの独自の機能を追加します。
抽象基本クラスの概念を円で囲みすぎているのではないかと思います。
抽象基本クラス (純粋なインターフェイスとは対照的に) は、その機能の一部が子クラスによって使用されることを意図したクラスです。したがって、オーバーライドされることを意図したメソッド (インターフェース部分) とともに、いくつかの機能が含まれます。この機能にメンバー変数を関連付けない理由はありません。
多くのフレームワークは継承に基づいています。これらには、ほぼ必然的に、メンバー変数を持つ抽象クラスが含まれます。たとえば、DirectShow は Windows のマルチメディア ストリーミング フレームワークです。ソース、エンコーダー、デコーダーなどはすべて、いわゆる「フィルター」に実装されています。さまざまな種類のフィルターの基本クラスがあります。それぞれに、アップストリーム フィルターとダウンストリーム フィルター、ネゴシエートされたメディア タイプなどのメンバー変数があります。