クラスのインスタンス化を妨げることは、それを抽象化する正当な理由ですか?たとえば、サブクラスGauge
とHeadingIndicator
があるAirSpeedIndicator
というクラスがある場合、Gauge
を抽象化することは良い考えですか? Gauge
のインスタンスは、それ自体ではほとんど役に立ちませんが、そのサブクラスへの参照として役立つ可能性があるためです。
通常、Abstract
クラスは、子クラスの1つで実装する必要があるいくつかのメソッドを持つクラスがある場合に使用されます。したがって、抽象クラスを見ると、次の一連の抽象メソッドも期待されます。実装する必要があります。
したがって、抽象クラスを使用してインスタンス化できないクラスを示すことはできますが、クラスのインスタンス化を他の人に止めさせたいのであれば、この方法が適しているとは思いません。
インスタンス化を防止したい場合は、親クラスのコンストラクタをprotected
として宣言することもできます。そうすれば、それを拡張するクラス以外の外部クラスからは見えなくなります。
public class Gauge
{
...
protected Gauge(...)
{
...
}
...
}
public class HeadingIndicator extends Gauge
{
...
public HeadingIndicator(...)
{
super(...);
}
...
}
public class AirSpeedIndicator extends Gauge
{
...
public AirSpeedIndicator(...)
{
super(...);
}
...
}
このように、Gauge
クラスのインスタンスを作成する手段は、拡張するクラスのみに制限されます。
これは、インスタンス化を防止する理由によって異なります。
インスタンスを制御したい場合は、シングルトンパターンでは、コンストラクタを非表示またはカプセル化します。
クラスがそれ自体ではインスタンスになり得ない一般化である場合、抽象クラスである方が理にかなっています。
あなたはすでにあなた自身に正しい質問をしています:特定のタイプのゲージは誰にとっても有用ですか?それは何を測定しますか?どの単位を使用していますか?お気づきのように、そうではありません。
したがって、ゲージはそれ自体をインスタンス化する必要があるものではありません。つまり、ゲージはおそらく抽象クラスまたはインターフェースのいずれかでなければなりません。私は通常、クラスインターフェイスを作成し、いくつかの一般的な動作のデフォルト実装を提供する必要がある場合は、そのインターフェイスの抽象クラス実装を適切に提供することを好みます。
ただし、考慮しなければならないことの1つは、ゲージがタイプであるかどうかであり、それは具体的に何をしているのかということになります。多くの「ゲージ」は、実際にはすべてのゲージに共通することは何もしません。この場合は、モデルを少し緩めることを検討してください。ゲージインターフェースがない場合もあります。 HeadingIndicatorとAirspeedIndicatorを、独立した無関係なクラスにします。または、これらのゲージを表示する統一された方法が必要で、Unit units()
、String labe()
、double measurement()
などのメソッドとのインターフェースが必要な場合もあります。
Tldrだと思います。ここで、これらの2つのエンティティを抽象親に抽象化するのが難しい/扱いにくいと思われる場合は、その抽象化は必要ないのでスキップできます。すべてのゲージに適用されるコードを書くつもりですか?そうでない場合は、親インターフェース/抽象クラスをスキップします。インターフェイスを必要とするコードのために、後でインターフェイスを抽出するのは簡単です。
私の観点からは、そうです。
唯一の問題は、クラスが必要か、それともインターフェースで十分か、ということです。
質問は次のとおりです。子クラス間で共通の動作(メソッド実装)があるので、共通の抽象クラスが必要ですか、それともメソッド宣言だけ(この場合は、インターフェースを使用するほうがよい)ですか?
D.
抽象クラスは、その実装の一部が欠落している可能性があることを意味します。私見、Gauge
だけでは役に立たないというのはあなたの意見であり、APIのすべてのユーザーの意見ではありません。
重要なメソッドが不足している場合にのみ、このようなクラスの抽象を宣言しますが、ユーザーがそのようなオブジェクトをインスタンス化できないようにすることを決して意味しません。
最初に、その特定のクラスに関するドキュメントを書き、それをそのまま使用しない理由を説明します。それから私は自分が本当にそのオブジェクトを使用できないようにしたいのかどうかを自問しますwhy(あなたのケースではそれが明確に定義されていないため)。
そして最後のステップは、特別なコンストラクターを使用するか、クラスを抽象化することです(しかし、これは、APIとオブジェクトの設計が悪いように感じるため、実際にはまだ実行しません)。