オブジェクト指向プログラミング(5) 静的分析(3)

Slides:



Advertisements
Similar presentations
オブジェクト指向 言語 論 第八回 知能情報学部 新田直也. 多相性(最も単純な例) class A { void m() { System.out.println( “ this is class A ” ); } } class A1 extends A { void m() { System.out.println(
Advertisements

クラス図(1) FM12013 山口 亨. クラスとは 現実に存在する “ 物体 ” (オブジェクト)の 構造や振る舞いなどに着目して注目し抽 象化したもの クラス図を含む UML のほとんどの図で使用 されている.
C++ 基礎. 目次 C++ とは? C++ におけるオブジェクト指向 課題 C++ とは? Cには足りなかったものが付与されて出来た物 具体的には、 情報の隠蔽(カプセル化) 共通の名前付け(関数のオーバーロード) 再利用の仕組み クラスの導入 など オブジェクト指向 C++ では大規模なプログラミングの.
ソフトウェア工学 理工学部 情報システム工学科 新田直也. 演習問題 1 の解答例  入庫処理の DFD 酒屋の在庫問題の DFD( 入庫処理 ) 更新情報 在庫ファイル 更新処理 倉庫係 在庫不足リスト 在庫ファイル 出庫指示書 新規出庫 判定 出庫指示書 作成処理 出庫依頼 積荷票.
ソフトウェア工学 知能情報学部 新田直也. オブジェクト指向パラダイムと は  オブジェクト指向言語の発展に伴って形成され てきたソフトウェア開発上の概念.オブジェク ト指向分析,オブジェクト指向設計など,プロ グラミング以外の工程でも用いられる.  ソフトウェアを処理や関数ではなくオブジェク.
プログラミング言語論 第10回(演習) 情報工学科 木村昌臣   篠埜 功.
6.4継承とメソッド 6.5継承とコンストラクタ 11月28日 時田 陽一
アルゴリズムとデータ構造 第2回 線形リスト(復習).
Chapter3 クラス図(後半)             FM12014 劉鎧誠.
アルゴリズムとプログラミング (Algorithms and Programming)
オブジェクト指向プログラミング(4) 静的分析(2)
第4回 iPhoneアプリ開発勉強会 Objective-C 基礎講座 -クラス- 鷲見政明.
クラスその2∽(アドバンス)∽ 福岡工業大学  梶原 大慈       .
Javaのための暗黙的に型定義される構造体
第5回 iPhoneアプリ開発勉強会 Objective-C 「継承とクラス」
アルゴリズムとデータ構造1 2007年6月12日
Javaのインタフェース についての補足 2006年5月17日 海谷 治彦.
ユースケース図 FM12012 比嘉久登.
3-5 クラス図の関係その3 福本研究室 神田 祐輔.
オブジェクト指向プログラミング(2) OOPの三大要素 「クラス」「ポリモーフィズム」「継承」
CHAPTER1 UMLとオブジェクト指向の基本概念(2)
3-3 クラス図の関係その2.
クラス図(1) 後半 FM13010 村上 太一.
構造体.
UMLの概要と オブジェクト指向の 基本概念
第9章 オブジェクトの構築 日下部研究室 修士2年 秋本 浩平.
変数のスコープの設計判断能力 を育成するプログラミング教育
社会人学習講座 「Javaプログラミング概論」
第2章 Eclipseと簡単なオブジェクト 指向プログラミング
ユースケース図2-4~ FM11012 中島拓也.
第6回独習Javaゼミ 第6章 セクション4~6 発表者 直江 宗紀.
~手続き指向からオブジェクト指向へ[Ⅱ]~
オブジェクト指向 プログラミング 第十四回 知能情報学部 新田直也.
ソフトウェア工学 知能情報学部 新田直也.
アルゴリズムとプログラミング (Algorithms and Programming)
その他の図 Chapter 7.
独習JAVA 6.8 コンストラクタの修飾子 6.9 メソッドの修飾子 6.10 ObjectクラスとClassクラス 11月28日(金)
オブジェクト指向 プログラミング 第十一回 知能情報学部 新田直也.
オブジェクト指向 プログラミング 第十三回 知能情報学部 新田直也.
暗黙的に型付けされる構造体の Java言語への導入
プログラミング 4 記憶の割り付け.
オブジェクト指向 プログラミング 第十四回 知能情報学部 新田直也.
2005年度 データ構造とアルゴリズム 第3回 「C言語の復習:再帰的データ構造」
第10章 これはかなり大変な事項!! ~ポインタ~
C#言語ソースプログラムの原型 C言語 C#言語 Hello World! Hello Students! オマジナイ! 適当なクラス名
オブジェクト指向言語論 第十一回 知能情報学部 新田直也.
オブジェクト指向言語論 第八回 知能情報学部 新田直也.
オブジェクト指向 プログラミング 第十ニ回 知能情報学部 新田直也.
オブジェクト指向言語論 第十一回 知能情報学部 新田直也.
1-3 UMLの図(ダイアグラム) コンポーネント図 システムの物理的な構成を表現 ソフトウェアコンポーネントの依存性を表現
プログラミング言語論 第十三回 理工学部 情報システム工学科 新田直也.
ソフトウェア工学 知能情報学部 新田直也.
プログラミング言語論 第十一回 理工学部 情報システム工学科 新田直也.
C#プログラミング実習 第3回.
サブゼミ第7回 実装編① オブジェクト型とキャスト.
プログラム分散化のための アスペクト指向言語
4.プッシュダウンオートマトンと 文脈自由文法の等価性
データベース第3回目 意味ごとにテーブルを分ける
JAVA入門⑥ クラスとインスタンス.
オブジェクト指向言語論 第十一回 知能情報学部 新田直也.
オブジェクト指向言語論 第九回 知能情報学部 新田直也.
ソフトウェア工学 知能情報学部 新田直也.
オブジェクト指向言語論 第七回 知能情報学部 新田直也.
Javaとは Javaとはオブジェクト指向言語でJava VM(Java仮想マシン)と呼ばれるプログラム上で動作します。
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
TList リスト構造とは? 複数のデータを扱うために、 データの内容と、次のデータへのポインタを持つ構造体を使う。
オブジェクト指向言語論 第九回 知能情報学部 新田直也.
オブジェクト指向言語論 第十回 知能情報学部 新田直也.
C言語講座第5回 2017 構造体.
計算機プログラミングI 第10回 2002年12月19日(木) メソッドの再定義と動的結合 クイズ メソッドの再定義 (オーバーライド)
Presentation transcript:

オブジェクト指向プログラミング(5) 静的分析(3) 第7回 ソフトウエアの再利用 オブジェクト指向プログラミング(5) 静的分析(3)

継承とは(インヘリタンス、Inheritance) ①クラス定義の共通部分を別クラスにまとめ   ることで、コードの重複を排除する仕組み   である。 ②継承はオブジェクト指向におけるもっとも 改革的な発明といっても過言ではない。 ③継承を活用すれば、私たちは生産性、保   守性、拡張性を大幅に向上することがで   きる。

メカニズムとしての継承 定義:クラスがインスタンスを生成する際に、他のク ラスの属性/操作を借りてきて、自分と合成 定義:クラスがインスタンスを生成する際に、他のク       ラスの属性/操作を借りてきて、自分と合成      して1つのインスタンスを生成する仕組みで     ある。 次ページの図にて説明

メカニズムとしての継承 通常、オブジェクト指向では、1つのインスタンスは1つのクラスから生成されます。(右図) 一方、クラスが別のクラスを継承すると、そのクラスは自分のインスタンスを生成する際に継承しているクラスの属性や操作を自分と合成して1つのインスタンスとして生成する。(左図) これがオブジェクト指向独特で、かつ重要な概念である「継承」のメカニズム(仕組み)です。 では、いったいこの仕組みがどういうときに役に立つのでしょうか。

継承の目的 ①従来の手続き中心のアプローチでは、サブルーチンによる手続きの共通化というのは欠かせない概念です。これを「サブルーチンによる処理の共通化」といいます。 ②オブジェクト指向のようなクラス中心のアプローチでも、「クラスの一部を共通化する」という方法が存在します。これが継承の(プログラム的な面での)機能です。 継承の目的から考えて見たいと思います ①従来の手続き中心のアプローチでは、サブルーチンによる手続きの共通化というのは欠かせない概念でした。これは同じような処理を複数書くのは面倒だけではなく、その処理内容自体に変更があったときにはすべての場所を変更しないといけないという問題点があります。これはまったくもって非効率です。 それを解決するために考え出されたのが「サブルーチンによる共通化」です。 ②このように手続き中心のアプローチに手続きの一部を共通化するという方法があるように、オブジェクト指向のようなクラス中心のアプローチでも、「クラスの一部を共通化」するという方法が存在します。これがプログラム的な面での継承の機能です。

継承の目的 次に、分析的な視点から、継承という考え た場合、継承を使用する局面には、2種類 の場合があります。 ①「クラスの汎化」  次に、分析的な視点から、継承という考え  た場合、継承を使用する局面には、2種類  の場合があります。    ①「クラスの汎化」    ②「クラスの特化」 これまでは、プログラム的な面から見ましたので、次に、分析的な視点から継承という概念について説明します。 継承を使用する局面に2種類の場合があります。1つは「クラスの汎化」、もう一つは「クラスの特化」です。

汎化としての継承 ・汎化(Generalization)というのは、複数のクラスの共通概念を抽出して、独立したクラスとして実装することをいう。

汎化としての継承 オブジェクト指向では、「人物」とう抽象的概念を「生徒」と「教師」から別に切り出してクラス化し、独立したクラスとして扱う方法が用意されています。 今、以前学習塾管理システムの分析で抽出した、生徒クラスと教師クラスがあるとします。 並べてみるとわかりますが、「生徒」と「教師」には、多くの同名の属性や操作を持っています。これらは単に名前が同じだけでなく、実際に教師の氏名を取得する場合と生徒の氏名を取得する場合で、その処理内容が違うとは考えられません。 これをそれぞれのクラスに対していちいち別々に実装するのは、無駄と言えます。 C言語的な考えでは、共通の処理はグローバル領域に共通関数として実装するような方法で解決するのが一般的にだと思います。 では、どうやって解決するかを考えてみたいと思います。 ここで「教師」と「生徒」に注目します。また、この複数のクラスの間に類似性から考えて見ます。これらは、ともに社会を構成している「人間」、つまり「人物」です。オブジェクト指向と独特の抽象的な概念です。 そして、(図中の言葉) この「ある概念のうちの抽象的な部分をさらに別の概念として切り出して実装する」という仕組みを「汎化としての継承」といいます。

継承の分析 ①分析的な面から継承とは何かということを定義すると、「あるクラスが、別のクラスの性質をそのまま引き継ぐ」というものです。  (オブジェクト指向独自の、抽象化の方法) ②例を見てみましょう。 先ほどは、メカニズム面から継承を考えましたが、今度は分析的な面から継承とはなにかを考えて見たいと思います。 (図中①)

継承の分析 これは継承の記法です。詳細は、後で説明するとします。 これは、「生徒」というモノの中に存在している抽象的な概念である「人物」を、継承をもちいてクラス化して切り出した例です。 (以下次ページと同じ) この構造は、「生徒」という概念は「人物」という概念を引き継いでいる(継承している)、ということを意味しています。このような関係を一般的に「is-a関係」といいます。 つまり、「生徒is a 人物」というわけです。 継承は、このようなis-a関係を実現する際に使用します。

継承の分析 ・この構造は、「生徒」という概念は「人物」と いう概念を引き継いでいる(継承している)、 ということを意味します。  いう概念を引き継いでいる(継承している)、  ということを意味します。  これを、[is-aの関係」といいます。 ・「生徒 is a 人物」 ・継承は、このようなis-a関係を実現する際に  使用します。 前頁の説明

継承の分析 ・人物クラスのほうを「基底クラス(スーパー クラス)、生徒クラスのほうを「派生クラス (サブクラス)」であると、いいます。  クラス)、生徒クラスのほうを「派生クラス  (サブクラス)」であると、いいます。 ・継承には多重度という概念はない。 ・継承は必ず明確な上下関係があります。 図の説明 この場合、人物クラスのほうを「基底クラス(スーパークラス)」といいます。 生徒クラスのほうを「派生クラス(サブクラス)」といいます。 関連とは、クラス間に関連があるといいました。また、インスタンス間にも関連があります。継承の場合は、クラス間に継承関連があっても、そのインスタンス同士はかならずしも関連があるとはかぎりません。(多くの場合は他人)多重度はインスタンス間の対応関係を表す概念ですので、継承とは無関係です。 継承には、どちらが基底クラス、どちらが派生クラスというはっきりとした方向性があります。(とういう点でも関連とは異なる)お互いに継承し合うこともありません。

継承の記述 通常の関連同様、クラスの間を直線で結ぶ ことによって表現します。それだけでなく、そ の途中に三角形を配置して、その向きによっ てその方向性を表現します。 三角形の頂点側が基底クラス、底辺側が派 生クラスです。 継承の記法について説明します。 先ほどの継承の分析で出来てきた図にて説明します。 通常の関連同様、クラスの間を直線で結ぶ ことによって表現します。それだけでなく、そ の途中に三角形を配置して、その向きによっ てその方向性を表現します。 三角形の頂点側が基底クラス、底辺側が派 生クラスです。

継承の記述 基本的には、クラス図には基底クラスの方を 派生クラスより上に書きます。だから、三角 形は常に頂点が上を向いています。 次に、クラスからインスタンスについて見てみましょう。

生徒クラスのインスタンスの生成 クラスからインスタンスがどのように生成されるか見てみます。(右下の図) まず、人物クラスのインスタンスは人物クラスの構成そのままに生成されています。 では、生徒クラスのインスタンスはどうでしょう。それだけでは、属性・操作は少ない ですが、人物クラスを継承することによって、人物クラスの属性/操作を自分自身 と合成し、あたかも元から自分の属性/操作として存在していたかのようにインスタンス を生成します。実際に生徒クラスから生成されるインスタンスは、多くの属性/操作 を持つことになります。 動作としてみてみると 生徒クラスのインスタンスに対して「氏名設定」の操作を行った場合、生徒クラスに その操作が存在していなくても、基底である人物クラスにその操作が存在しているので、 あたかも生徒クラスに自体にその操作が存在しているように動作します。 操作する側から見た場合、「氏名設定」の操作が、生徒クラスに実装されているか、 あるいは基底の別のクラスに実装されているのかはまったく意識する必要はありません。 使う側からは、「生徒クラス」とその基底クラスは、まったく1つのクラスとして意識します。

生徒クラスのインスタンスの生成 ①人物クラスを継承することによって、人物クラスの属性/操作を自分自身と合成し、あたかも元から自分の属性/操作として存在していたかのようにインスタンスを生成する。

生徒クラスのインスタンスの生成 ②操作する側から見た場合、「氏名設定」の操作が、生徒クラスに実装されているか、あるいは基底の別のクラスに実装されているのかはまったく意識する必要はありません。 ③使う側からは、「生徒クラス」とその基底クラスは、まったく1つのクラスとして意識します。

継承のメリット 今までは、メカニズム、或いは分析的な面を見てきました。しかし それらはいったいどのようなメリットがあるのか考えてみたいと思います。 図を見てください。 このように、多くの類似したクラスが共通の基底クラスとして「人物」クラス を持つことができます。 これによって、すでに人物クラスが存在していれば、教師クラスでは、人物クラス に当たる部分の分析、実装、テスト、デバッグ、保守全ての作業が必要なくなります。 つまり、その部分のプログラムを書く必要がないということになります。 また、クラスの共通化は、拡張性、保守性の面でもメリットがあります。

継承のメリット ①多くの類似したクラスが共通の基底クラスとして「人物」クラスをもつことができます。  これによって、人物クラスが存在していれば、教師クラスでは、「人物」に当たる部分の分析、設計、実装、テスト、デバッグ、保守、全ての作業が必要なくなります。つまり、その部分のプログラムを書く必要がなくなるということになります。

継承のメリット ②汎化によるクラスの共通化は、拡張性、保守性の面でメリットがあります。

継承のメリット 年齢 生徒クラスと教師クラスに「年齢」という属性を追加する場合を考えてみましょう。 ・生徒と教師の共通の基底クラスである「人物」クラスに対して「年齢」属性を  追加することによって、生徒クラスと教師クラスの両方で、自動的に年齢という  属性が追加されたのと同じ動作をすることになります。

継承のメリット 生徒クラスと教師クラスに「年齢」という属性 追加する場合を考えてみよう。 ・生徒と教師の共通の基底クラスである「人  物」クラスに対して「年齢」属性を追加する  ことによって、生徒クラスと教師クラスの両  方で、自動的に年齢という属性が追加され  たのと同じ動作をすることになる。

汎化としてのまとめ 不適切な属性の付加 人物クラスにIDコードをという属性を持たせてしまったら IDカードを持たない保護者まで、その属性がふられてしまう。 もう一つ例を見てみましょう。 もう一度、学習塾管理システムに「IDコード」という概念があったとします。 これは、生徒、教師ともに、塾に入るときにIDカードをカードリーダに通す ことによって、システムに読み込まれるコードで、一人一人にユニークに振られる コードです。 これは、生徒、教師両方のクラスに共通の属性です。これを人物クラスに含めて しまってよいかです。(あまり深く考えないとします) ここで、その学習塾管理システムで新たに「保護者」クラスが必要になったとします。 保護者is-a人物である以上は人物クラスから派生させることができます。 しかし、人物クラスにIDコードを持たせてしまったら、IDカードも持たない保護者 にまでその属性が振られることになってしまいます。 現実の世界で「人物」全てにIDコードがふられていないことからも、適切でないこと がわかると思います。 このような場合、次ページのようにあらたなクラスを派生させて考えて見ます。 現実の世界で考えると「人物」すべてにIDコードが振られることとなり適切でないことなる。

汎化としてのまとめ Is-aの関係 Is-aの関係 Is-aの関係 Is-aの関係 人物食クラスにIDコードを付与するのではなく、 人物クラスから新たに「塾が管理する人物」クラスを派生させます。 さらにそこから「生徒」「教師」を派生させるのが適切です。 そして、「保護者」クラスは、人物クラスから派生させます。 こうすることにより、全てのクラス間には、「is-aの関係」が成り立ちます。 このように、ものごとの抽象的な部分に着目し、まるで世の中の成り立ちを考えるように 概念の階層を構築し、基底クラスを分離、実装してくのが「汎化」という作業です。

特化としての継承 ・特化(Specialization)というのは、あるクラスを基にして、それを特殊化したクラスを派生クラスとして作ること。  たとえば、塾に「奨学生」という制度があったとします。 たとえば、塾に「奨学生」という制度があったとします。 ここで、継承してみます。

特化としての継承 「生徒」を基底クラスにして、「奨学生」クラスを派生させる。つまり「奨学生」is-a「生徒」という継承関連を結ぶ(左図)。 このようにして、継承をしようすれば、生徒クラスを基にしていろいろな特別な生徒クラスを派生させていくことができます。 どれだけクラスを派生させたとしても、元の生徒クラスにはまったく手を加える必要がない。 「生徒」を基底クラスにして、「奨学生」クラスを派生させる。 つまり「奨学生」is-a「生徒」という継承関連を結ぶ(左図)。 このようにして、継承を使用すれば、生徒クラスを基にしていろいろな特別な 生徒クラスを派生させていくことができます。 どれだけクラスを派生させたとしても、元の生徒クラスにはまったく手を加える必要がありません。 基底である生徒クラスは派生クラスの影響を受けることなく、従来通り単独で使用することができます。 基底クラスは派生クラスからは完全に独立した存在です。 継承は、複数のクラスの共通部分を抽出するためでなく、 あるクラスを基にして、そのクラスの特殊な形のクラスを作成することができる。 これを「特化」といいます。

特化としての継承 ①基底クラスは、派生クラスから完全に独立 した存在です。  した存在です。 ②継承は、複数のクラスの共通部分を抽出するためでなく、あるクラスを基にして、そのクラスの特殊な形のクラスを作成することができる。これを「特化」といいます。

汎化と特化 汎化と特化をまとめると。 ①「汎化」は、基底クラスを作ること ②「特化」は、派生クラスを作ること 元のクラスがどちらであるかということが違う だけで、メカニズムとしては同じものです。

プログラムレベルでの継承の例 「文字列の最後にスペースがついていた場合にそれを除去する」という処理の例 基底クラスである「文字列」クラスにはまったく手を加えることなく、機能が追加された文字列クラスを手にいれることができる。 「文字列の最後にスペースがついていた場合にそれを除去する」という処理の例です プリグラムを作成しているとき、文字列クラスのメンバ関数にするほどでもない、必要性も ない。つまり「再利用したいけど、いつでも必要というほどの処理ではない。」、このような中途半端に 重要な処理というのが実はかなりあるということを経験したことはないでしょうか。 そのようなときは継承の出番です。 このような場合、文字列クラスを特化させた「末尾がスペースの場合それを除去することができる文字列クラス」 を作るのが適当です。 これによって、基底クラスである「文字列」クラスにはまったく手を加えることなく、 機能が追加された文字列クラスを手にいれることができます。という例です。 これは、派生クラスの中に1つ、「末尾のスペースを除去」という操作を実装するだけです。 そうすれば、その派生クラスのインスタンスを生成すれば、文字列の設定や長さの取得など、 基底クラスの属性や操作はそのまま引き継がれ、まるで派生クラスにそのまま実装されている かのように使用することができます。 これで継承を使用してできた派生クラス「末尾のスペースを除去できる文字列クラスが完成 しました。

カスタマイズの手段としての継承 クラスの拡張 ①属性や操作が増える。 ②操作それ自体の処理内容の変更。 ③高度なカスタマイズのような拡張。  ①属性や操作が増える。  ②操作それ自体の処理内容の変更。  ③高度なカスタマイズのような拡張。 このような問題を解決する方法が継承には用意されています。 それは、操作のオーバーライドです。 継承を利用すれば、それぞれのクラスの独立性も保ったまま、属性や操作を付加してクラスを拡張し、 新しいクラスを続々と作ることが可能です。これが継承の基本的な使用方法です。 ところで、クラスを拡張するといっても、単に属性や操作が増えるだけではありません。 操作それ自体の処理内容の変更、高度なカスタマイズのような拡張もあると思います。 このような問題を解決する方法が継承には用意されています。 それは、操作のオーバーライドです。

カスタマイズの手段としての継承 操作のオーバーライド ・基底クラスのメンバ関数とまったく同じ名前のメン バ関数を派生クラスに実装することをいいます。 ・派生クラスのインスタンスの中には、基底クラス と派生クラスの2つの同じな名のメンバ関数が衝 突していることをいいます。 つまり、派生クラスの操作が基底クラスの操作を 横取りしてしまう方法です。 操作のオーバーライド ・基底クラスのメンバ関数とまったく同じ名前のメンバ関数を派生クラスに実装することをいいます。 ・派生クラスのインスタンスの中には、基底クラスと派生クラスの2つの同じな名のメンバ関数が  衝突していることをいいます。 つまり、派生クラスの操作が基底クラスの操作を横取りしてしまう方法です。(次ページの図参照)

カスタマイズの手段としての継承 派生クラスのほうにも「文字列設定」という操作を用意して、 基底の文字列クラスにある「文字列設定という操作を乗っ取ってしまう方法です。

カスタマイズの手段としての継承 派生クラスにある操作が優先して実行されます。 「文字列」クラスをカスタマイズしたにもかかわわず、その文字列クラスにはまったく手を触れる必要がない。 実際の動きを見てみましょう。 派生クラスのインスタンスに対して「文字列設定」が発行されます。 そのクラスインスタンスは、まず派生クラスのほうのメンバ関数の中に 「文字列設定」という操作が存在しているか調べます。 用意されていなければ、自動的に基底クラスの「文字列設定」が呼び出されます。 しかし、派生クラスにも同じ名前の操作が重複して存在している場合には、 派生クラスにある操作が優先して実行されます。 よって、派生クラスに、末尾スペースを除去するという機能を含めた「文字列設定」 を重複して実装すれば、処理を横取りでき、カスタマイズできた、ということに なります。 これで、既存の文字列クラスを基にして、操作をたった1つ追加しただけで、「末 尾のスペースが必ず削除される文字列」クラスを新しく作成したことになります。 なぜなら、「文字列」クラスをカスタマイズしたにもかかわらず、その文字列クラスには まったく手を触れる必要がないのです。

継承関係を導入したクラス図 インベーダゲームのクラス図に継承関係を 導入してみよう!

継承関係を導入したクラス図

継承の実装 LIST11:人物クラスから生徒クラスを派生 // person.h // 人物クラス class Person { int age ; // おなじみの属性 char * name ; public : virtual void setname ( char * name ) ; virtual void setage ( int age ) ; : } ;

継承の実装 // student.h // 生徒クラス // クラスを継承する際には,必ず基底クラスの宣言部が必要 #include "person.h" class Student : public Person // ここで継承している!! { int schoolyear ; // 学年(生徒独自の属性) : } ;

継承の実装 LIST12:生徒クラスの使用例 #include "student.h" // クラスが宣言されている // ヘッダファイルをインクルードする // 生徒クラスの使用例 main () { Student suzuki ; // Studentクラスのインスタンス生成 // 基底のPersonクラスのメンバ関数を呼ぶことができる suzuki . setage ( 15 ) ; :

継承の実装 LIST13:派生クラスから基底クラスへのアクセス class Base // 基底クラス { virtual void private_func () { // プライベートメンバ関数 puts ("プライベートメンバ関数") ; } public : virtual void public_func () { // パブリックメンバ関数 puts ("パブリックメンバ関数") ; } ; class Derived : public Base // Baseを継承している // 基底クラスのメンバ関数を呼ぶメンバ関数の例 virtual void foo () public_func () ; // OK private_func () ; // コンパイルエラー! :

多重継承(Multiple Inheritance) 多重継承とは。 「基底クラスを複数持つような継承」

多重継承 ある人事管理システムがあったとします。 その中で、「管理職社員」クラス、そして、「営業職社員」クラスがあるとします。 管理職社員には、その管理職が管理している「部署の名前」が属性として存在し、 また、営業職社員には「営業成績」が属性として存在します。 さて、営業課長はどのように分析されるべきでしょうか。 課長くらいでしたら、外回りはしないでも、実際の成績になるような営業も行う かもしれません。よって、管理職であると同時に営業職でもあるわけです。 つまり「管理職社員」クラスと「営業職社員」クラスの両方のクラスとis-a関連 があります。 したがって、上図は、問題があります。管理職はすべて営業職になってしまっています。 では、どのように実現するかというと、このような時に使用されるのが「多重継承」です。 つぎの例

多重継承 このように、営業課長は「管理職社員」であると同時に、営業成績が存在する「営業職社員」 でもあります。 このように、1つのインスタンスが複数の面を持ち、それをシステムとして実現しなといけない 場面は少なくはないでしょう。このように現実に対応するように考えられたのが多重継承です。 多重継承は、あるクラスの基底クラスとして、1つだけでなく複数のクラスを持つことができる、 ということです。上図がそれを表しています。 このようにすれば、営業課長のインスタンスに対して、営業成績を問い合わせることもできます、 管理している課の名前を聞くこともできます。 このように多重継承すれば、「営業管理職社員」クラスは、すべての属性と操作を「管理職社員」 と「営業職社員」から引き継ぐことができ、特別な実装はなにも必要ありません。

多重継承が表す概念 ・1つのインスタンスが複数の面を持ち、それ をシステムとして実現しないといけないという ことは非常によくあることです。 ・このような現実に対応するように考えられた のが「多重継承」です。 ・あるクラスの基底クラスとして、1つだけで なく複数のクラスを持つことができる。

多重継承の実装 リスト-1 営業社員クラスと管理職社員クラス class TradeStaff // 営業職クラス { リスト-1 営業社員クラスと管理職社員クラス class TradeStaff // 営業職クラス { unsigned long sales ; // 売上 : } ; class ManagementStaff // 管理職クラス String * sectionName ; // 管理している部署へのポインタ

多重継承の実装 リスト-2:「営業管理職社員(TradeManagementStaff)」クラス class TradeManagementStaff : public TradeStaff , public ManagementStaff { // 営業管理職クラス : : } ;

多重継承の実装 リスト-3:「営業管理職社員(TradeManagementStaff)」クラスの利用方法 foo () { // 営業管理職の鈴木さん TradeManagementStaff suzuki ; : // 営業職クラスのメンバ関数を呼べる // (営業成績の取得) sales = suzuki . getSales () ; // 管理職クラスのメンバ関数も呼べる // (管理している部署名の取得) puts ( suzuki . getSectionName () ) ; :