2

構成の簡単なコード例についての回答を探していました。構成と継承の違いは知っていますが、コードを使用して理解することはできません。

構成を使用する必要がある理由に関する比較ベースの例 (両方のアプローチを使用) は非常に役立ちます。

前もって感謝します

4

3 に答える 3

1

基本的な違いは、継承がコンパイル時にクラス階層を修正するのに対し、合成では実行時に合成されたクラスの関係を決定できることです。

継承で、継承階層でコードを固定しました。たとえば、 CircleクラスからShapeクラスを継承する場合、クラスShapeの基底クラスとして固定されCircleます。

Shape を2DShape、 、 とさらに分類するとし3DShapeます。Circle継承により、クラスが から継承することはできなくなりました2DShape

コンポジションなら可能です。したがって、構成されたクラスを、実行時に構成されたクラスの派生型のいずれかに変更できます。

于 2013-09-28T15:59:20.417 に答える
1

おそらく、継承よりも合成をチェックしたいかもしれません

継承よりも構成を優先することは、設計の柔軟性を高め、ビジネス ドメイン クラスと長期的に安定したビジネス ドメインを提供する設計原則です。つまり、HAS-A は IS-A 関係よりも優れている可能性があります。

コード例との違いを説明している関連投稿でaleemb回答を確認してください

これは、継承よりも構成を好む理由を説明する便利なリンクです

構成と継承の両方でコードを再利用できますが、継承の欠点の 1 つは、カプセル化が壊れることです。サブクラスがその動作をスーパークラスの振る舞いに依存していると、突然壊れやすくなります。スーパー クラスの動作が変更されると、サブ クラスの機能が壊れる可能性があります。コードを脆弱にする継承の一例は、HashSet のメソッド add() と addAll() です。HashSet の addAll() が add() メソッドを呼び出して実装されている場合、HashSet のサブクラスを記述して、HashSet に挿入する前にコンテンツを暗号化するとします。オブジェクトを HashSet に挿入できるメソッド add() は 1 つしかないため、これらのメソッドをオーバーライドし、add() をオーバーライドして encrypt() メソッドを呼び出します。addAll() は add() を使用して実装されているため、これは自動的に addAll() もカバーします。非常に魅力的に見えます。よく見ると、スーパークラスの動作に依存しているため、この実装が脆弱であることがわかります。基本クラスがパフォーマンスを向上させ、add() メソッドを呼び出さずに addAll() を実装する場合、以下の例は壊れます。

public class EncryptedHashSet extends HashSet{
.....

public boolean add(Object o) {
   return super.add(encrypt(o));
}

}

継承を支持してコンポジションを使用した場合、この問題に直面することはなく、スーパークラスの動作に依存しなくなるため、クラスはより堅牢になります。代わりに、追加部分にスーパークラスメソッドを使用しているため、以下の例に示すように、 addAll() の改善によりメリットが得られます。

public class EncryptedHashSet implements Set{
private HashSet container;

public boolean add(Object o) {
   return container.add(encrypt(o));
}

public boolean addAll(Collection c) {
   return conatainer.add(encrypt(c));
}

.......
}
于 2013-09-28T15:59:58.587 に答える
0

Joshua Bloch が最もよく言っていると思います:項目 16: 継承よりも構成を優先する

于 2013-09-28T16:03:59.860 に答える