6

私は最近、オブジェクト指向プログラミングの良い習慣として、クラスからの継承を常に許可する必要があると言われました。私は本当にそうは思いませんが、私は私の心に確固たる議論を持っていません。

ブロックされた継承の実際の例:

  1. C ++ STLクラス(特殊なクラステンプレート)では、継承(非仮想デストラクタを持つ)は許可されません。
  2. Javaにはfinal、のような多くの標準コンポーネントに適用されるクラス修飾子がありますjava.lang.String

私が思う考えられる理由は次のとおりです。

  1. サブクラスが機密性の高い内部にアクセスする可能性があるため、セキュリティ。(私はそうは思いません-彼らはプライベートメンバーにアクセスしません。)
  2. パフォーマンス。サブクラスは、メンバー関数の一部をオーバーライドすることにより、効率的な実装を台無しにする可能性があるためです。(子は非仮想関数をオーバーライドしません。)
  3. 継承よりも構成を強制するため。(私は完全に同意します。必要のない場合は継承を優先すべきではありません。)

だから私の質問は:どのような状況で私は意図的に継承をブロックする必要がありますか?

4

3 に答える 3

4

実際、私が従おうとしている、そしてJoshBlochが彼のEffectiveJavaの本で推奨している慣習は、あなたが言われたものとは正反対のルールです。継承について考えていない限り、クラスは継承されるように設計されています。 、およびクラスを継承する方法を文書化した場合は、常に継承を無効にする必要があります。

効果的なJavaのこの章を読んで(購入したことを後悔することはありません)、このルールについて話した人に見せることをお勧めします。

継承を禁止する最も明白な理由は不変性です。不変オブジェクトは使いやすく(1つの状態のみ)、キャッシュして多くのオブジェクト間で共有でき、本質的にスレッドセーフです。クラスが継承可能である場合、誰でもクラスを拡張し、可変属性を追加することでクラスを可変にすることができます。

于 2012-05-05T17:52:56.693 に答える
4

初心者にとっては、他の人にクラスを拡張させたくないと確信している場合にのみ、継承を許可しないでください。些細な理由(パフォーマンスなど)で継承を防止することは、通常はお勧めしません。コードの再利用は、クラスにマークを付けることで達成できるわずかなパフォーマンスの向上を上回ることが多いためfinalです。

そうは言っても、継承を明示的に防止したい場合のいくつかの例を次に示します。

  1. あなたは商用のクローズドソースクラスを書いていて、人々が将来的に機能を変更できるようにしたくありません。人々があなたのメソッドをオーバーライドしたり、クラスを拡張したりして、予期しない結果が得られていると不平を言っている場合、後でサポートを提供する必要がないため、これはクラスの継承を防ぐ良い理由です。

  2. 不変のクラスを設計しています。クラスにマークを付けることfinalで、サブクラスがクラスの不変の動作を損なうのを防ぎます。たとえば、サブクラス化が許可されている場合String、他の人が独自の実装を作成して、をString変更できるようにすることができます。これで、型をとるコードでString、オブジェクトが不変であることを確認できなくなりました。

  3. 継承よりも合成を強制したい。これは、クラス間の密結合を避けたい場合(つまり、相互に大きく依存しているクラスのグループが必要ない場合)に適しています。

  4. コンパイラによるインライン化を奨励したい。クラスとメソッドをfinalとしてマークすると、実行時にオブジェクトを呼び出すためにJavaが適切なクラスメソッドを検索する必要がなくなるため、パフォーマンスがわずかに向上する可能性があります。非finalメソッドは仮想としてマークされているため、必要に応じて適切に拡張できます。finalメソッドは、クラス内で直接リンクまたはインラインでコンパイルできます。これを行うことで達成できるパフォーマンスの向上は、多くの場合、重要ではないことに注意してください(特に、クラスのメソッドが大きい場合)。

于 2012-05-05T18:39:12.333 に答える
3

これについては私の0.02だけ...

クラスの継承を許可すると、人々は予期しない問題に対処できるようになります。(例:RoRで頻繁に発生するモンキーパッチ。醜い場合もありますが、現実と衒学者の違いです)。そうは言っても、私は無償の継承の大ファンではありません。ベースクラスとサブクラスの関係は脆弱な場合があります。深い継承階層を理解するのは困難です。

継承を禁止することを考えることができる1つのケースは、不変性を強制することです。これは、JavaStringクラスなどにとって重要です。

于 2012-05-05T17:53:39.807 に答える