質問

Javaでの継承を禁止する正当な理由は何ですか。たとえば、最終クラスを使用するか、単一のプライベートなパラメーターなしのコンストラクターを使用するクラスを使用するなどです。メソッドを最終的にする良い理由は何ですか?

役に立ちましたか?

解決

ここでの最良の参照は、ジョシュア・ブロッホの優れた本「Effective Java」のアイテム19です。 (これは、第2版の項目17と第1版の項目15です。)本当に読んでおくべきですが、要約します。

祖先が継承されるように設計されていない場合、継承されたクラスとその親との相互作用は驚くべきものであり、予測不可能です。

したがって、クラスには2種類あります。

  1. クラス 拡張 に設計されており、その方法を説明するのに十分なドキュメント

  2. クラスマーク最終

純粋に内部コードを書いている場合、これは少しやり過ぎかもしれません。ただし、クラスファイルに5文字を追加するための追加作業は非常にわずかです。内部消費のみを記述している場合、将来のコーダーは常に「最終」を削除できます-「このクラスは継承を念頭に置いて設計されていません」という警告と考えることができます。

他のヒント

メソッドをfinalにして、オーバーライドするクラスが他のメソッドで期待される動作を変更できないようにすることができます。コンストラクタで呼び出されるメソッドはしばしばfinalとして宣言されるため、オブジェクトを作成するときに不快な驚きを感じることはありません。

クラスをfinalにする理由の1つは、継承よりも合成を強制したい場合です。これは一般に、クラス間の密結合を回避するのに望ましいです。

最終方法に進むことができる3つのユースケースがあります。

  1. 派生クラスが特定の基本クラス機能をオーバーライドすることを回避するため。
  2. これは、派生クラスが変更しないはずのフレームワークのいくつかの重要なコア機能を基本クラスが提供するセキュリティ目的のためです。
  3. finalメソッドとprivateメソッドには仮想テーブルの概念を使用しないため、finalメソッドはインスタンスメソッドよりも高速です。そのため、可能性がある場合は、最終メソッドを使用してみてください。

クラスをファイナルにするための目的:

ボディがこれらのクラスを拡張して動作を変更できないようにします。

例:ラッパークラスIntegerは最終クラスです。そのクラスが最終クラスでない場合、誰でも整数を自分のクラスに拡張し、整数クラスの基本的な動作を変更できます。これを避けるために、javaはすべてのラッパークラスを最終クラスとして作成しました。

不変オブジェクトを作成できます( http://en.wikipedia.org/wiki/Immutable_object )、シングルトン( http://en.wikipedia.org/wiki/を作成することができます。 Singleton_pattern )、または効率、安全性、またはセキュリティの理由で、誰かがメソッドをオーバーライドできないようにすることができます。

継承はチェーンソーのようなものです-非常に強力ですが、間違った手ではひどいです。継承するクラスを設計するか(柔軟性が制限され、時間がかかります)、禁止する必要があります。

有効なJava 2ndエディションの項目16および17、または私のブログ投稿&quot ;相続税"

うーん... 2つのことを考えることができます:

特定のセキュリティ問題を扱うクラスがあるかもしれません。サブクラス化して、サブクラス化されたバージョンをシステムに提供することにより、攻撃者はセキュリティ制限を回避できます。例えば。アプリケーションはプラグインをサポートする場合があり、プラグインがセキュリティ関連のクラスをサブクラス化できる場合、このトリックを使用してサブクラス化されたバージョンを何らかの方法で密輸できます。ただし、これはむしろアプレットなどに関してSunが対処しなければならないものであり、おそらくそのような現実的なケースではありません。

もっと現実的なのは、オブジェクトが可変になるのを避けることです。例えば。文字列は不変なので、コードはそれへの参照を安全に保持できます

 String blah = someOtherString;

最初に文字列をコピーする代わりに。ただし、文字列をサブクラス化できる場合は、文字列値の変更を許可するメソッドを追加できます。これにより、上記のように文字列をコピーするだけで文字列が同じままになることをコードが信頼できなくなり、代わりに文字列。

人々が自分自身や他の人を混乱させるようなことをしないようにするため。定義済みの定数または計算がある物理ライブラリを想像してください。 finalキーワードを使用しないと、誰かがやって来て、決して変わらないはずの基本的な計算や定数を再定義できます。

また、商用のクローズドソースクラスを書いている場合、特にユーザーがサポートを提供する必要があり、メソッドをオーバーライドして不満を言っている場合は、機能を最終的に変更できるようにしたくないかもしれませんそれを呼び出すと、予期しない結果が得られます。

クラスおよびメソッドをfinalとしてマークすると、ランタイムが特定のオブジェクトを呼び出すために適切なクラスメソッドを検索する必要がないため、パフォーマンスがわずかに向上することがあります。非最終メソッドは仮想としてマークされているため、必要に応じて適切に拡張でき、最終メソッドはクラス内で直接リンクまたはインラインでコンパイルできます。

クラスをオーバーライドしても動作が変わらないように、メソッドをfinalにする必要があります。動作を変更できるようにするには、メソッドをパブリックにします。パブリックメソッドをオーバーライドすると、変更できます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top