「オブジェクト指向プログラミング」の版間の差分

削除された内容 追加された内容
Ef3 (トーク | 投稿記録)
タグ: 2017年版ソースエディター
Ef3 (トーク | 投稿記録)
→‎包含、継承、および委譲: 定義リストを(リンク可能なように)節に分割。
タグ: 2017年版ソースエディター
85 行
 
=== 包含、継承、および委譲 ===
;==== 包含 ====
:オブジェクトは、そのインスタンス変数に他のオブジェクトを含めることができますが、これを包含(オブジェクト・コンポジション; ''object composition'' )といいます。
:たとえば、Employee クラスのオブジェクトは、"first_name" や "position" といった自身のインスタンス変数に加えて、Address クラスのオブジェクトを (直接またはポインタを介して) 含むことができます。
;=== 継承 ===
:オブジェクト指向プログラミングをサポートしている言語は、ほとんどの場合、継承をサポートしています。
:これにより、クラスを「~である」という関係を表す階層に配置することができます。
:例えば、Employee クラスは Person クラスを継承しています。
:親スーパークラス(継承元)で利用できるデータやメソッドは、サブクラス(継承先)にも同じ名前で表示されます。
:例えば、Person クラスは、"first_name" と "last_name" という変数を "make_full_name()" というメソッドで定義しています。
:これらはEmployeeクラスでも使用可能で、Employeeクラスには変数 "position "と "salary "が追加されるかもしれません。
:この手法では、同じプロシージャやデータ定義を簡単に再利用できるだけでなく、現実世界の関係を直感的に反映できる可能性があります。
:開発者は、データベースのテーブルやプログラミングのサブルーチンを利用するのではなく、ユーザーがより慣れ親しんでいるであろうオブジェクト、つまりアプリケーション・ドメインのオブジェクトを利用します。
:サブクラスは、スーパークラスで定義されたメソッドを[[#オーバーライド|オーバーライド]]できます。
:;=== 多重継承 ===
::一部の言語では多重継承が可能ですが、オーバーライドの解決が複雑になる可能性があります。
::多重継承が可能な言語では、[[#Mix-in|Mix-in]]は単なるクラスであり、is-a-type-ofの関係を表していません。
:;MIx=== Mix-in ===
::Mix-inは通常、複数のクラスに同じメソッドセットを追加するために使用されます。
::例えば、UnicodeConversionMixinクラスは、共通の親を持たないFileReaderクラスとWebPageScraperクラスにインクルードすることで、unicode_to_ascii()というメソッドを提供することができます。
:;=== 抽象クラス ===
::抽象クラスは、インスタンス化してオブジェクトにすることはできません。
::抽象クラスは、インスタンス化できる他の「具象」クラスに継承するためにのみ存在します。
{{See also|Java/抽象クラス|C++/クラスの定義や継承#純粋仮想関数|Crystal#抽象クラス|Scala#抽象クラス}}
:Javaでは、クラスがサブクラス化されるのを防ぐためにfinalキーワードを使用することができます。
 
=== Java: final class ===
:Javaでは、クラスがサブクラス化されるのを防ぐためにfinalキーワードを使用することができます。
final class MyFinalClass {
. . .
}
継承よりも構成を重視する考え方は、継承の代わりに構成を用いてhas-a関係を実装することを提唱しています。
例えば、Employee クラスは、Person クラスを継承する代わりに、Employee オブジェクトに内部の Person オブジェクトを与えることができ、Person クラスが多くの公開属性やメソッドを持っていても、外部のコードから隠すことができます。
Goのように、継承を全くサポートしていない言語もあります。
 
=== 開放/閉鎖原則 ===
オープン[[W:開放/クローズの閉鎖原則]]」とは、クラスや関数は「拡張に対してはオープンであるが、変更に対してはクローズであるべき」と提唱するものです。
 
=== 委譲 ===
[[W:デリゲート (プログラミング)|委譲]]( ''Delegation'' )もまた、継承の代わりに使用できる言語機能の一つです
 
=== 継承よりも合成 ===
継承よりも成を重視する考え方( ''Composition over inheritance'' )は、継承の代わりに成を用いてhas-a関係を実装することを提唱しています。
例えば、Employee クラスは、Person クラスを継承する代わりに、Employee オブジェクトに内部の Person オブジェクトを与えるこ(プライベートな)メンバー変数して持つ戦略、Person クラスが多くの公開属性やメソッドを持っていても、外部のコードから隠すことができます。
 
==== Go: 継承を構文としてはサポートしない ====
[[Go]]は、継承を全くサポートしません。ただしGoは、構造体のメンバーのメンバーをメンバー名を間に狭まずに参照することができるので、実質的に包含と継承の区別がありません。この仕組は、「名前が衝突したらどうするんだ!」と批判されることがありますが、通常の継承でもメンバー名の衝突は解決しなければいけないので、問題が増えるわけではありません。
 
[TODO:Goのコードで説明]
委譲(''Delegation'')もまた、継承の代わりに使用できる言語機能の一つです
 
=== ポリモーフィズム ===