質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

デザインパターン

デザインパターンは、ソフトウェアのデザインでよく起きる問題に対して、解決策をノウハウとして蓄積し再利用出来るようにした設計パターンを指します。

Q&A

解決済

3回答

4431閲覧

OOPにおけるComposition over inheritanceの所以について

tachikoma

総合スコア3601

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

デザインパターン

デザインパターンは、ソフトウェアのデザインでよく起きる問題に対して、解決策をノウハウとして蓄積し再利用出来るようにした設計パターンを指します。

0グッド

1クリップ

投稿2018/03/19 05:57

質問:Composition over inheritanceについて

オブジェクト指向の勉強をしているなかで、"Composition over inheritance"というフレーズを見かけたのですが、よく分からなかったので質問させてください。非常にブロードな中身は承知しておりますので、teratailにふさわしくなければご指摘ください。

オブジェクト指向

表題のComposition over inheritanceを調べる中で、次のようなQiitaの記事(
オブジェクト指向と10年戦ってわかったこと)を見つけました。この中では初めに、

オブジェクト指向は「カプセル化」「継承」「ポリモーフィズム」の3つの原則を守ることで成り立つ

とあります。ただ、この記事の中ほどで、

継承は親クラスの機能を受け継ぐ機能です。しかしこれは継承の本質ではありません
継承の本質はインターフェイスです。

とあります(太字のハイライトは質問者である私が付けました)。記事ではJavaを題材にインターフェイスを説明しており、これによってポリモーフィズムを実現している、とあります。

そのあとの内容も読んだ上での理解としては、例えばクラスAを継承したクラスBは、

  • 「B is A」の関係にある => クラスBが「何であるか」を重視??
  • 親クラスの機能も引き継ぐ

という特徴がある一方で、Compositionだと(必要な要素をまとめあげることによって)、

  • クラスA, クラスBはそれぞれ「何ができるか」を重視する。
  • インターフェイスは共通だが、必ずしも機能を引き継ぐ必要はない。

と特徴づけられると考えました。

質問内容

上記の二つ(継承とインターフェイス)はお互いに排反なするものではなく、共存するものだと承知しているのですが、なぜ「Composition over inheritance」と言われるようになったのでしょうか。

設計などの柔軟性が上がる、等のデザインパターンの優位性を訴えるものも見かけたのですが、経験が浅くいまいちピンときませんでした。もしよろしければこのフレーズの背景や、実際に役に立った等の情報をお教え願えませんでしょうか。

長くなりましたが、どうぞよろしくお願いします。

補足情報(FW/ツールのバージョンなど)

調べてみたもの一覧。

https://en.wikipedia.org/wiki/Composition_over_inheritance

https://www.youtube.com/watch?v=wfMtDGfHWpA

https://medium.com/humans-create-software/composition-over-inheritance-cb6f88070205

Composite パターン

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

Compositionだと(必要な要素をまとめあげることによって)、

. クラスA, クラスBはそれぞれ「何ができるか」を重視する。
. インターフェイスは共通だが、必ずしも機能を引き継ぐ必要はない。

と特徴づけられると考えました。

この捉え方はダックタイピングでの考え方に通じると思います。

こういう使い方をする際にはよく「機能を継承するのではなく、ある機能を持ったものをソフトウェアを構成する部品としてその一部の機能だけを流用」としたくなり、そんな場合にComposition over inheritanceパターンがよくマッチするということのように思いました。

https://adtech.cyberagent.io/scalablog/2015/03/30/RubyistがScalaを勉強した話(続き)/
https://qiita.com/ikedaosushi/items/45652e53c06c761d8137

一方「意味的には同じ型として扱いたいのだけど、継承で実装すると基底クラスの振る舞いに強く依存した実装になるため、それを嫌ってComposition over inheritanceを使う」といった記事もみあたります。

http://blog.livedoor.jp/mocoh/archives/268897.html

この記事に出てくるパターンは「何かを継承しようとしてハタと困る」典型的なパターンであるように思います。

例えばJavaのInputStreamなどに機能を追加したクラスを定義しようとしたとき、(A)int read()と(B)int read(byte[])の関係はどうなってるんだろう?みたいな迷いが生じることがありますね。リファレンスにはっきり書かれていることもありますが、どちらをoverrideすべきなのか、上位クラスの「実装を見ないことにはわからない」場合もよくある気がします。そんなときに「派生させるのではなくComposition over inheritanceとする」ことで、再利用するクラスの実装とは独立した実装が安全・確実・頑強にできるという感じでしょうか。
よくドキュメント化された基底クラスについては自然に派生クラスを定義できることもあるけれどいつもいつもそれが容易とは限らないというわけです。

自分は「実装の独立性を高めるという利点」がComposition over inheritanceの利点であるように思いました。

投稿2018/03/19 09:11

KSwordOfHaste

総合スコア18392

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tachikoma

2018/03/19 09:26

確かに、ドキュメント化されているか、安全な拡張と言えるか、は重要ですね。
guest

0

こんにちは。

上記の二つ(継承とインターフェイス)はお互いに排反なするものではなく、共存するものだと承知している

その通りと思います。

なぜ「Composition over inheritance」と言われるようになったのでしょうか。

「継承とインタフェースが共存すること」と「Composition over inheritance」の概念は別に相反しないと思います。「Composition over inheritance」と呼ばれるデザインパターンがあるというだけではないでしょうか?
Wikipediaをざっと見る限り、単に多重継承を避けるための一手段に過ぎないように感じます。(JavaやC#は多重継承をサポートしていませんし。)

投稿2018/03/19 06:55

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

多くの言語で基底クラスは1つしか指定できませんので、

  • 複数の基底クラスから派生させることができない
  • 機能を変える際に、あとから基底クラスを差し替えるのが難しい

など、あとあとクラスに手を入れる上で足かせとなることがあります(C++では多重継承が可能ですが、それもそれで別な問題を引き起こします)。Compositionであれば、インターフェースさえ守れば実装は親クラスからの制約がなく自由に可能です。

投稿2018/03/19 06:53

maisumakun

総合スコア145121

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問