だから私は構成と継承を学んでいます。これで、継承は「is-a」型の関係であり、合成は「has-a」の関係であることがわかりました。しかしこれは、コンポジションが何かのオブジェクト (またはフィールド) を持つクラスを単に参照することを意味するのでしょうか?
2 に答える
基本的にはありますが、それにはより多くの意味があります。
外部オブジェクトは、データの破損を避けるために、囲まれたオブジェクトを変更から保護する必要があります。これは通常、防御コピーの作成によって行われます。囲まれたオブジェクトが不変の場合、これは必要ありません
その他の意味としては、囲んでいるオブジェクトをオブジェクト API から分離して、将来変更される可能性があることです。オブジェクトが配列を使用し、代わりにリストを使用することを決定したとしましょう。内部オブジェクトへの参照を禁止することにより、外部は既存のクライアントを壊すことなく実装を変更できます。
「Effective Java Book」の「継承よりも構成を優先する」の章を参照してください。
クラスが別のクラスを拡張する(継承) か、別のクラスをフィールドとして使用する(構成)状況がある場合は、構成に進みます。これにより、クラスを使用するコードに影響を与えずに後で実装を変更できるためです。
そうしないと、実装が拡張クラスのサブクラスになるように永久にロックされます。いつやってもダメです。
構成よりも継承が選択された JDK の例は、内部でを使用し、適切なインターフェイスを実装するだけでよい場合に、 を拡張Properties
するクラスです。つまり、単純な匿名クラスなど、Properties クラスの独自の実装を置き換えることはできません。 Hashtable
Hashtable
HashMap
JDK には、たとえばを使用するなど、適切な例がはるかに多くありますがHashtable
、コントラクトや API に影響を与えることなく、他のハッシュベースのクラスを使用するように簡単に変更できます。
実装においてクラスを柔軟にするよう常に努力する必要があります。Liskov 置換原理
を参照してください。