web-dev-qa-db-ja.com

クラスで「final」を使用することが本当にそれほど悪いのはなぜですか?

PHP OOPレガシーWebサイトをリファクタリングしています。

私はクラスで「_」を「make it explicit that the class is currently not extended by anything "。これは、クラスに来て、protectedプロパティまたはメソッドの名前を変更/削除/変更できるかどうか疑問に思っています。もし私がreally wantクラスを拡張するには、拡張のために最後のキーワードnlock itを削除するだけです。

つまり、子クラスのないクラスに来た場合、クラスに最終マークを付けることでその知識を記録できます。次にアクセスするときには、コードベースに子があるかどうかを確認するためにコードベースを再検索する必要はありません。したがって、リファクタリング中の時間を節約できます。

それはすべて、賢明な時間節約のアイデアのように見えますが...まれに/特別な場合にのみクラスを「最終」にする必要があることをよく読んでいます。

多分それはモックオブジェクトの作成を台無しにするか、私が考えていない他の副作用があります。

何が欠けていますか?

34
JW01

私は、クラスを「最終的な」ものにするのはまれで特別な場合にのみ行うべきだとよく読んでいます。

それを書いた人は誰でも間違っています。自由にfinalを使用してください。問題はありません。これは、クラスが継承を考慮して設計されていないことを文書化しています。これは通常、デフォルトですべてのクラスに当てはまります。意味のある継承可能なクラスを設計するには、final指定子を削除するだけでは不十分です。多くの注意が必要です。

したがって、デフォルトでfinalを使用することは決して悪いことではありません。実際、多くの人々はこれがデフォルトであるべきだと提案しています。 ジョン・スキート

多分それはモックオブジェクトの作成を台無しにする…

これは確かに警告ですが、クラスをモックする必要がある場合は、いつでもインターフェースに頼ることができます。これは、すべてのクラスをあざける目的で継承に対してオープンにするよりも確かに優れています。

54
Konrad Rudolph

クラスにサブクラスがないというメモを自分に残したい場合は、必ずそれを行い、コメントを使用してください。 「最終的な」キーワードはコメントではなく、言語のキーワードを使用して何かを知らせるためだけに使用することは(そして、あなただけがそれが何を意味するかを知っているだけです)、悪い考えです。

8
Jeremy

"クラスをfinalと宣言するタイミング" に関する素晴らしい記事があります。それからのいくつかの引用:

TL; DR:インターフェースを実装し、他のパブリックメソッドが定義されていない場合は、クラスを常にfinalにします

なぜfinalを使用する必要があるのですか?

  1. Doomの大規模な継承チェーンの防止
  2. 励みになる構成
  3. 開発者にユーザーのパブリックAPIについて考えさせる
  4. 開発者にオブジェクトのパブリックAPIを圧縮させる
  5. finalクラスは常に拡張可能にすることができます
  6. extendsはカプセル化を解除します
  7. その柔軟性は必要ありません
  8. コードは自由に変更できます

finalを避けるべき時:

最終クラスは、以下の仮定の下でのみ効果的に機能します。

  1. 最終クラスが実装する抽象(インターフェース)があります。
  2. 最終クラスのすべてのパブリックAPIは、そのインターフェースの一部です

これら2つの前提条件の1つが欠けている場合、コードが抽象化に完全に依存していないため、クラスを拡張可能にする時点に到達する可能性があります。

追伸素晴らしい読書をしてくれた@ocramiusに感謝!

5
Nikita U.

クラスの「最終」とは、サブクラスが必要なことを意味します。 「final」サブクラスを好きなだけ削除してください。機能しない場合でも不満はありません。あなたは一人でいます。

クラスをサブクラス化できる場合、それは他のユーザーが依存する動作であり、サブクラスが従う抽象用語で記述する必要があります。呼び出し元は、ある程度の変動を想定して作成する必要があります。ドキュメントは注意深く書く必要があります。ソースコードがまだないので、「ソースコードを見る」とは言えません。それはすべての努力です。クラスがサブクラス化されることを期待していない場合、それは不必要な作業です。 「最終」は、この努力がなされていないことを明確に述べ、公正な警告を与えます。

5
gnasher729