クラスはそのサブクラスを知る必要がありますか?たとえば、クラスは特定のサブクラスに固有の何かを行う必要がありますか?
私の本能は、それは悪いデザインであり、ある種のアンチパターンのように思えます。
クラスはそのサブクラスを知る必要がありますか?たとえば、クラスは特定のサブクラスに固有の何かを行う必要がありますか?
私の本能は、それは悪いデザインであり、ある種のアンチパターンのように思えます。
回答:
クラスの概念によって暗示される答えは「いいえ」です。
処理しているアクション、データ、またはリレーションがすべてのサブクラスの一部である場合、実際の型を確認せずにスーパークラスで処理する必要があります。または、一部のサブクラスにのみ適用されます-実行時の型チェックを実行して正しいことを行う必要があり、他の誰かがそれを継承するたびにスーパークラスを変更する必要があります(または静かに間違ったことをする可能性があります)派生クラスの変更は、変更されていないスーパークラスなどを壊す可能性があります。
要するに、多くの悪い結果をもたらしますが、それは通常、そのような解決策を手に負えないほど十分に悪いものです。複数のサブクラスが同じことを行い、コードの重複を避けたい場合(実際には常に良いことです)、より良い解決策は、すべてのサブクラスがコードを継承できる中間レベルのクラスを導入することです。
だけでなく、必要があり、それは知りません、それは単にすることはできません!通常、クラスはいつでもどこでも拡張できます。作成された時点では存在していなかったクラスによって拡張できます。
一部の言語では、拡張クラスをスーパークラスで制御できます。Scalaでは、クラスをとしてマークできますsealed
。これは、同じコンパイル単位(ソースファイル)内の他のクラスによってのみ拡張できることを意味します。それらのサブクラスがある場合を除きしかし、また sealed
あるいはfinal
、サブクラスは、その後さらに他のクラスによって拡張することができます。
Scalaでは、これは閉じた代数データ型のモデル化に使用されるため、標準的なHaskell List
型は次のようになります。
data List a = Nil | Cons a (List a)
次のようにScalaでモデル化できます。
sealed trait List[+A]
case object Nil extends List[Nothing]
final case class Cons[+A] extends List[A]
そして、あなたはそれを保証できるだけので、それら二つのサブ「クラス」が存在しList
ているsealed
ため、ファイルの拡張外にすることはできません、Cons
ですfinal
ので、すべての延長とすることができないNil
でobject
、とにかく拡張することができません。
しかし、これは特定のユースケース(継承による代数的データ型のモデリング)であり、この場合でも、スーパークラスは実際にはそのサブクラスについては知りません。これは、より多くのことを保証していたユーザのList
彼はのケース差別をした場合、その種類Nil
やCons
、任意のは存在しません、他の背中の後ろに飛び出る代替。
abstract internal
メンバーを追加することです。
簡単な答えはいいえです。
コードが脆弱になり、オブジェクト指向プログラミングの2つの基本原則が損なわれます。
はい、時々。たとえば、限られた数のサブクラスが存在する場合。ビジターパターンは、このアプローチの有用性の説明図です。
例:明確に定義された文法の抽象構文ツリー(AST)ノードは、Node
すべてのノードタイプを処理するビジターパターンを実装する単一のクラスからすべて継承できます。
Node
もちろん、基本クラスには、そのサブクラスへの直接参照は含まれていません。ただしaccept
、Visitor
パラメータを持つメソッドが含まれています。そして、Visitor
含まれているvisit
各サブクラスごとにメソッドを。そのNode
ため、サブクラスへの直接参照はありませんが、Visitor
インターフェースを介して間接的にサブクラスを「認識」します。それらはすべてそれを介して結合されました。
ある企業向けにコンポーネントを作成し、後で退職した後、誰かがそれを自分の目的に合わせて拡張した場合、そのことを通知する必要がありますか?
いや!
クラスでも同じです。あなたの本能を信頼。