オブジェクト指向設計

このページでは、カプセル化・クラス・継承などの基本用語、is-a関係とpart-of関係、ポリモーフィズム、UMLのクラス図やシーケンス図の読み方がわかります。

  • 一言で言うと:
    • 世の中の「モノ」を、データと処理をひとまとめにした部品(オブジェクト)としてソフトの中に再現し、モノどうしがメッセージで仕事を頼み合う、という作り方の話
    • その設計図を描くための共通言語がUML

基本の用語(カプセル化・クラス・継承)→ クラスどうしのつながり(is-a・part-of)→ 便利な仕組み(ポリモーフィズムなど)→ 図にする(UML)

覚え方の軸

  • オブジェクト=「データ(属性)+処理(メソッド)」のセット
    • 中身は隠し(カプセル化)、外からはメッセージで頼む
    • データ中心設計の「標準データと標準プロセスの一体化」を、さらに進めた考え方
  • クラスは「型紙」、インスタンスは「型紙から作った実物」
  • クラスどうしの関係は2つだけ
    • is-aは「〜は…の一種」。汎化⇔特化、スーパクラス/サブクラス、継承される
    • part-ofは「〜は…の一部」。集約⇔分解、集約クラス/部分クラス
  • 「オーバー○○」は2つ
    • オーバーライドは、親のメソッドを子が上書きする(親子の間、縦)
    • オーバーロードは、同じクラスに同じ名前で引数違いのメソッドを並べる(同じクラスの中、横)
  • UMLの図は「形(構造)」と「動き(振る舞い)」に分ける
    • 形はクラス図、オブジェクト図
    • 動きはユースケース図、シーケンス図(時間の順)、コミュニケーション図(つながり)、ステートマシン図(状態)、アクティビティ図(処理の流れ)

前置き:オブジェクト指向とは

  • オブジェクト指向:
    • データ中心アプローチの考え方を、さらに進めたもの
    • データだけでなく、実世界の「物」の構造と振舞いに注目する
    • 「物」や「物どうしの関係」をソフトで表して、実世界の仕組みをそのままコンピュータ上に再現しようとする
    • 例えば、銀行のシステムなら、「口座」「お客さん」「ATM」をそれぞれ1つのモノとして作り、モノどうしがやりとりする形で組み立てる

オブジェクト指向の基本概念:特有の用語を押さえる(★)

① オブジェクトとカプセル化

  • オブジェクト:
    • 一般には、操作の対象であるデータのこと
    • オブジェクト指向では、データそのものではなく、データ(属性)と、そのデータに対する手続(メソッド)を1つにまとめたもの
  • 属性:
    • オブジェクトが持つデータ
  • メソッド:
    • 属性を操作する手続
    • オブジェクトのインタフェース部分といえる。メッセージに対応する処理を書く
  • カプセル化(★):
    • データ(属性)と、それを操作する手続(メソッド)を一体化し、オブジェクトの実装の詳細を内部に隠すこと
  • 情報隠ぺい:
    • オブジェクトの実装の詳細を、内部に隠すこと
  • カプセル化の効果:
    • オブジェクトの内部のデータ構造やメソッドの実装を変えても、他のオブジェクトが影響を受けにくい
    • そのため、独立性が高まり、再利用しやすくなる
    • 例えば、テレビのリモコン。中の回路がどうなっているか知らなくても、ボタン(メソッド)を押せば使える。中の回路を作り変えても、ボタンが同じなら使う人は困らない
  • メッセージ:
    • オブジェクトどうしが作業を依頼するときに使うもの
    • オブジェクトのメソッドを動かしたり、オブジェクトどうしの相互作用のために使う
  • オブジェクト指向の動き方:
    • 個々のオブジェクトに、そのオブジェクト固有の操作(作業)を割り振る
    • オブジェクトどうしが、互いに作業を頼み合いながら機能する
  • 例:
    • 「注文」オブジェクトが、「在庫」オブジェクトに「引当て」というメッセージを送る
    • 受け取った「在庫」では引当てメソッドが実行され、応答(引き当てられたかどうか)を返す

② クラスとインスタンス

  • クラス:
    • いくつかの似たオブジェクトに共通する性質を抜き出し、属性やメソッドを一般化(抽象化)して定義したもの
    • オブジェクトの定義情報といえる
    • クラスはテンプレート(雛形)
  • クラスライブラリ:
    • クラスを集めたもの
  • インスタンス:
    • クラスをもとに作られた、具体的な値を持ったオブジェクト(実体)
    • クラスを定義しただけでは実体はなく、クラスの使用宣言をしてはじめて実体が作られる
  • 例:
    • クラス「会員」は、属性が会員番号・氏名・ランク、メソッドが「ポイントをためる」
    • インスタンス1は「M001、佐藤、ゴールド」、インスタンス2は「M002、鈴木、シルバー」
  • クラスとインスタンスの例え:
    • たい焼きの型がクラス、焼き上がった1個1個のたい焼きがインスタンス
    • 型だけではお腹はふくれない(実体がない)

③ インヘリタンス(継承)

  • インヘリタンス(継承)(★):
    • クラスをさらに抽象化して上位クラスを作ると、上位クラスの属性やメソッドを下位クラスが受け継ぐ性質
  • 継承の効果:
    • 新しい下位クラスを作るとき、上位クラスと同じ属性やメソッドは定義しなくてよい
    • そのクラスで定義が必要な部分(差分)だけを定義すればよい
  • 差分プログラミング:
    • 差分だけを定義する手法
  • 例:
    • 上位クラス「図形」に、円・三角形・四角形に共通する性質(色、位置など)を定義する
    • 下位クラス「円」「三角形」「四角形」は、図形の性質を継承するので、改めて定義しなくてよい
  • 上位クラス(基底クラス):
    • クラス階層の最上位にあるクラス、または、派生クラスの元になるクラスを基底クラスという
  • 下位クラス(派生クラス):
    • あるクラスを継承して作ったクラス
  • 多重継承:
    • 複数のクラスから属性やメソッドを継承すること
    • C++では可能だが、Javaでは許可されていない
    • 補足:Javaでもクラスの多重継承はできないが、インタフェースは複数実装できる

クラス間の関係:「一種」か「一部」か(★)

  • クラス間の関係:
    • 階層構造を持つ上位クラスと下位クラスのつながりには、「is-a関係」と「part-of関係」がある
is-a関係 part-of関係
別名 汎化-特化関係 集約-分解関係
意味 「〜は…である」(一種) 「〜は…の一部である」
例 円 is-a 図形(円は図形の一種) キーボード part-of パソコン(キーボードはパソコンの一部)
上にまとめる 汎化 集約
下に分ける 特化 分解
上位クラスの呼び名 スーパクラス 集約クラス
下位クラスの呼び名 サブクラス 部分クラス

① is-a関係

  • is-a関係(汎化-特化関係):
    • 「〜は…である」という関係
    • 例えば、「円 is-a 図形」は、円は図形であるという意味
  • 汎化:
    • 下位のクラスに共通する性質をまとめて、上位クラスを定義すること
    • 例えば、円・三角形・四角形の共通点をまとめて「図形」を作る
  • 特化:
    • 上位クラスの性質を具体化し、個別の部分を加えて下位クラスを定義すること
    • 例えば、「図形」を具体化して「円」を作る
  • is-a関係の性質:
    • 「B is-a A」のBのオブジェクトがいくつ欠けても、Aのオブジェクトは成り立つ
    • 例えば、円がなくなっても、「図形」という分類はなくならない
  • スーパクラス/サブクラス:
    • is-a関係の上位クラスがスーパクラス、下位クラスがサブクラス

② part-of関係

  • part-of関係(集約-分解関係):
    • 「〜は…の一部である」という関係
    • 例えば、「パソコン」は「本体」「キーボード」「ディスプレイ」などに分解でき、逆にそれらを組み合わせると「パソコン」になる
  • 集約:
    • 上位クラスを構成する下位クラスをまとめ上げること
    • 例えば、本体・キーボード・ディスプレイを組み合わせてパソコンにする
  • 分解:
    • 上位クラスを下位クラスに細かく分けていくこと
  • 集約クラス/部分クラス:
    • part-of関係の上位クラスが集約クラス、下位クラスが部分クラス
  • 見分け方:
    • 「BはAの一種?」と聞いて自然ならis-a、「BはAの部品?」と聞いて自然ならpart-of
    • 例えば、「キーボードはパソコンの一種」はおかしいので、キーボードとパソコンはpart-of

オブジェクト指向で使われる概念:便利な仕組み(★)

① ポリモーフィズムとオーバーライド

  • ポリモーフィズム(多相性・多様性):
    • 同じメッセージを送っても、オブジェクトごとに違う動作をする性質
  • ポリモーフィズムのイメージ:
    • 上位クラス「図形」に「面積を求める」があり、下位クラスの「円」は「半径×半径×円周率」、「四角形」は「縦×横」で計算する
    • 実行時にどの図形かを気にせず、「図形」に「面積を求めよ」とメッセージを送る
    • すると、実際の図形によって、違う計算をする
    • 身近な例では、「鳴け」と言うと、犬は「ワン」、猫は「ニャー」と鳴く
  • オーバーライド(★):
    • ポリモーフィズムを実現するために、スーパクラスで定義されたメソッドを、サブクラスで書き直す(再定義する)こと
    • オーバーライドすることで、サブクラスごとに違う性質を持てる

② 抽象メソッドと抽象クラス

  • 抽象メソッド:
    • 継承の性質を逆に利用して、スーパクラスにはメソッドの名前だけを定義し、実際の動作は定義しないメソッド
    • スーパクラスの中では実装されない
  • 抽象クラス:
    • 抽象メソッドを持つクラス
    • 共通の概念を定義するためだけのクラス
    • メソッドの実装がないので、インスタンスを作れない
  • 具象クラス:
    • 抽象クラスを継承し、抽象メソッドをオーバーライド(再定義)したサブクラス
    • 具象クラスでインスタンス化する
  • 抽象クラスの例え:
    • 「図形」という形そのものは描けない(インスタンスを作れない)。描けるのは「円」や「四角形」(具象クラス)
    • 「図形」には「面積を求める」という名前だけ決めておき、どう計算するかは円や四角形がそれぞれ決める

③ その他の概念

概念 中身 例え
オーバーロード 同じクラスの中に、メソッド名が同じで、引数の型・個数・並び順が違うメソッドを複数定義する。似た機能に同じ名前を付けられるので、クラス構造が簡潔になる 「支払う」に、現金を渡すか、カードを渡すかで別の処理を用意する
委譲 あるオブジェクトへの操作を、その内部で他のオブジェクトに頼むこと。他のオブジェクトの操作を再利用することになる 店長が客の注文を受けて、実際の調理はコックに任せる
伝搬 あるオブジェクトに操作をしたとき、関連する他のオブジェクトにも自動的にその操作が適用されること フォルダを削除すると、中のファイルも一緒に削除される

UML:オブジェクト指向の設計図の共通言語(★午後にもよく出る)

  • UML(Unified Modeling Language):
    • オブジェクト指向の分析・設計で使うモデリング言語
    • ここでは、UML2.0の主な図法を扱う
  • SysML(Systems Modeling Language):
    • UML仕様の一部を再利用し、機能を追加・拡張したモデリング言語
    • システムの分析・設計のほか、妥当性確認や検証にも使う
    • SysMLで導入されたパラメトリック図で、モデル要素間の制約条件を書ける
    • そのため、複数のシステムを組み合わせて実現するSoS(System of Systems)のモデル化にも向いている
  • 試験での出方(試験):
    • 午後問題では、クラス図やシーケンス図の空欄を埋める問題がよく出る
    • 問題文のシナリオに合わせて、2つの図を照らし合わせると、空欄に入るものが絞り込める

① クラス図

  • クラス図:
    • 対象領域にあるクラスと、クラス間の関連を表す図
    • クラスとクラスを線で結び、線の先に記号を付けて、汎化や集約などの関係を示す
  • クラスの書き方:
    • 箱の上段にクラス名、中段に属性(「属性:型」)、下段に操作(「操作:戻り値の型」)を書く
    • 属性や操作を重視するときは書く。クラス間の関係だけを重視するときは、属性と操作を省略する
  • +:
    • 他のクラスからも参照できる
  • -:
    • 自クラスのみで参照できる
  • #:
    • 自クラスと、その派生クラスからのみ参照できる
関係 記号 意味
関連 A ── B(ただの線) クラスA、Bの間に、何らかの関係がある
汎化 A ◁── B(白い三角がA(親)側) BはAの一種で、Aを継承している
集約 A ◇── B(白いひし形がA(全体)側) BはAの部品。ただし、Bは他のクラスの部品でもよい(複数のクラスでBを共有できる)
コンポジション A ◆── B(黒いひし形がA(全体)側) 集約より強い関係。AからBを切り離せない。Aが削除されるとBも削除される
依存 A ←┄┄ B(点線の矢印がAを指す) BはAに依存している。BはAの変更の影響を受ける
  • 集約とコンポジションの違い:
    • 全体と部品が独立して存在できるなら「集約」
    • 全体と部品が一体化していて、生存期間が同じなら「コンポジション」
    • 例えば、チームと選手は集約(チームが解散しても選手は残る)。家と部屋はコンポジション(家を壊すと部屋もなくなる)
  • 記号の覚え方:
    • 三角もひし形も、親や全体の側に付く
    • ひし形は、中身が白(空っぽ)なら弱い集約、黒(詰まっている)なら強いコンポジション
  • 多重度:
    • 相手のクラスのインスタンスが、いくつ対応するかを、線の端に書く
  • n:
    • nのみ
  • n..m:
    • nからmまで
  • n..*:
    • n以上(「0..*」は0以上)
  • n,m:
    • nかm
  • 例題(多重度の読み方):
    • 「チーム 1 ◇── 0..* 選手」と「注文 1 ◆── 1..* 注文明細」がある。何がわかるか
  • 例題の答え:
    • チームは、選手を0人以上持つ。選手は、1つのチームに属する(集約)
    • 注文は、注文明細を1つ以上持つ。注文明細は、1つの注文に属し、注文が削除されると注文明細も削除される(コンポジション)
    • 多重度は、相手側の線の端に書かれた数を読む(チームから見た選手の数は、選手の側に書かれた「0..*」)
  • オブジェクト図:
    • クラス図がクラス間の関連を表すのに対し、実際に実体化されたインスタンス(オブジェクト)どうしの関連を表す図
    • 構造はクラス図に対応する

② シーケンス図

  • シーケンス図:
    • オブジェクト間の相互作用を、時間の流れに沿って表す図
    • 横にオブジェクトを並べ、縦で時間の経過を表す(上から下へ時間が進む)
    • オブジェクト間でやりとりするメッセージは、矢印で表す
  • メッセージ(呼出し):
    • 他のオブジェクトの操作(メソッド)を呼び出すメッセージは、実線の矢印
  • 応答メッセージ:
    • 破線の矢印
  • ライフライン(生存期間):
    • オブジェクトから下に伸びる点線
    • オブジェクトが作られてから消えるまでの期間
  • アクティベーション(活性区間):
    • ライフラインの上の細長い箱
    • オブジェクトが実際に動作している期間
  • 内部呼出し:
    • オブジェクトが、自分自身のメソッドを呼び出すこと
  • シーケンス図の例え:
    • 電話のやりとりを時系列で書いたメモ。誰が誰に、いつ電話して、いつ返事が来たかがわかる
  • コミュニケーション図:
    • シーケンス図が時間の流れを重視するのに対し、オブジェクト間の関連(データリンク)を重視した図
    • UML1.xでの名前は、コラボレーション図

③ その他の主な図

図 何を表すか 主な部品
ユースケース図 システムの範囲を長方形で囲み、システムが提供する機能(ユースケース)と、利用者(アクタ)とのやりとりを表す アクタ(人形)、ユースケース(楕円)、システム境界(長方形)
ステートマシン図 オブジェクトの状態遷移図。受け取ったイベントと、それに伴う状態の遷移、アクションを表す 初期状態、状態、遷移(イベント/アクション)、最終状態
アクティビティ図 システムやユースケースの処理の流れを表す。フローチャートのUML版。順次処理、分岐処理のほかに、並行処理や処理の同期を表せるのが特徴 開始、処理の内容、分岐([条件])、終了
  • アクタ:
    • システムの利用者や、システムとやりとりする外部システム
    • 人だけでなく、外部のシステムもアクタになる(ひっかけ注意)
  • ユースケース:
    • システムの機能や振舞い
  • ステートマシン図の別名:
    • 状態マシン図、状態機械図ともいう
    • UML1.xでの名前は、ステートチャート図
    • 前に出た状態遷移図のUML版
  • アクティビティ図とペトリネット図:
    • どちらも並行処理や同期を表せる
  • 図の選び方:
    • 「誰が何に使うか」ならユースケース図
    • 「どの順番でやりとりするか」ならシーケンス図
    • 「どの状態からどの状態へ移るか」ならステートマシン図
    • 「処理がどう流れるか(並行もあり)」ならアクティビティ図

混同しやすいペア

  • 属性 / メソッド
    • 属性は、オブジェクトが持つデータ
    • メソッドは、属性を操作する手続(メッセージに対応する処理)
  • カプセル化 / 情報隠ぺい
    • カプセル化は、データと手続を一体化し、中身を隠すこと
    • 情報隠ぺいは、実装の詳細を内部に隠すこと(カプセル化で実現される)
  • メッセージ / メソッド
    • メッセージは、オブジェクトへの作業の依頼
    • メソッドは、依頼を受けて実行される処理
  • クラス / インスタンス
    • クラスは、雛形(定義情報)。実体はない
    • インスタンスは、クラスから作った、具体的な値を持つ実体
  • クラス / クラスライブラリ
    • クラスは、オブジェクトの定義情報
    • クラスライブラリは、クラスを集めたもの
  • 基底クラス / 派生クラス
    • 基底クラスは、最上位のクラス、または継承の元になるクラス
    • 派生クラスは、あるクラスを継承して作ったクラス
  • 継承 / 多重継承
    • 継承は、上位クラスの属性やメソッドを受け継ぐ
    • 多重継承は、複数のクラスから受け継ぐ(C++は可能、Javaは不可)
  • is-a関係 / part-of関係
    • is-aは、「一種」の関係(汎化-特化)
    • part-ofは、「一部」の関係(集約-分解)
  • 汎化 / 特化
    • 汎化は、共通点をまとめて上位クラスを作る
    • 特化は、上位クラスを具体化して下位クラスを作る
  • 集約 / 分解
    • 集約は、部品をまとめ上げる
    • 分解は、全体を細かく分ける
  • スーパクラス・サブクラス / 集約クラス・部分クラス
    • スーパクラスとサブクラスは、is-a関係での呼び名
    • 集約クラスと部分クラスは、part-of関係での呼び名
  • オーバーライド / オーバーロード
    • オーバーライドは、スーパクラスのメソッドをサブクラスで再定義する
    • オーバーロードは、同じクラスに、同じ名前で引数が違うメソッドを複数定義する
  • ポリモーフィズム / オーバーライド
    • ポリモーフィズムは、同じメッセージで違う動作をする「性質」
    • オーバーライドは、それを実現する「やり方」
  • 抽象クラス / 具象クラス
    • 抽象クラスは、抽象メソッドを持ち、インスタンスを作れない
    • 具象クラスは、抽象メソッドをオーバーライドし、インスタンスを作れる
  • 委譲 / 伝搬
    • 委譲は、受けた操作を他のオブジェクトに頼む
    • 伝搬は、操作が関連するオブジェクトにも自動的に適用される
  • 集約 / コンポジション
    • 集約(白いひし形)は、部品が独立して存在できる。他のクラスと共有してもよい
    • コンポジション(黒いひし形)は、全体と部品が一体で、全体が消えると部品も消える
  • 汎化 / 依存
    • 汎化(白い三角の実線)は、継承している
    • 依存(点線の矢印)は、相手の変更の影響を受ける
  • + / - / #
    • +は、他のクラスからも参照できる
    • -は、自クラスのみ
    • #は、自クラスと派生クラスのみ
  • クラス図 / オブジェクト図
    • クラス図は、クラスどうしの関連
    • オブジェクト図は、インスタンスどうしの関連
  • シーケンス図 / コミュニケーション図
    • シーケンス図は、時間の流れを重視する
    • コミュニケーション図は、オブジェクト間の関連を重視する(旧名はコラボレーション図)
  • ライフライン / アクティベーション
    • ライフラインは、オブジェクトが作られてから消えるまで(点線)
    • アクティベーションは、実際に動作している期間(細長い箱)
  • 呼出しメッセージ / 応答メッセージ
    • 呼出しは、実線の矢印
    • 応答は、破線の矢印
  • ステートマシン図 / アクティビティ図
    • ステートマシン図は、オブジェクトの状態の移り変わり(旧名はステートチャート図)
    • アクティビティ図は、処理の流れ(フローチャートのUML版。並行処理も書ける)
  • UML / SysML
    • UMLは、オブジェクト指向の分析・設計のモデリング言語
    • SysMLは、UMLを拡張したもので、システムの妥当性確認や検証、SoSのモデル化にも使う(パラメトリック図)

← 09 開発技術の目次に戻る

タイトルとURLをコピーしました