エンジニアの知識

オブジェクト思考とは? OOPを簡単な例で理解しよう!

2020年3月17日

オブジェクト指向Object-Oriented/OO)とは、世の中の物事をオブジェクトと、その振る舞いで定義する考え方です。

特にオブジェクト指向プログラミングObject-Oriented-Programming/OOP)という言葉で使用されることが一般的です。

今回はこのOOPについて、「人間をオブジェクト思考で定義する」ことを例にして解説します。

オブジェクト思考の例:人間クラスを定義する

様々な人種が並んで勉強をしている

簡単な例として、人間をOOPで定義してみます。

まず人間には「性別」があり、それぞれ「名前」があります。加えて、人間は「配偶者」として別の人間と関係をもつ人と、もたない人がいます。

また良好な人間関係を築くために「挨拶」をします。

  1. 人間は個々に名前をもつ
  2. 人間はそれぞれ性別をもつ
  3. 人間は配偶者をもつことがある
  4. 人間は挨拶として「Hello」と言える

この例における1~3のような属性のことを「プロパティ」と言い、4番目のような能力のことを「メソッド」と言います。

この例で定義する人間は、3つの属性「名前・性別・配偶者」があり、「挨拶」という1つのメソッドがあります。

人間クラスの定義例
人間クラスの定義例

この例のような、「物事の基本となる定義」をOOPでは「クラス」と言います。

この定義を「人間クラス」と呼称しましょう。

 

なお、OOPにおいては、「すべてのオブジェクトはかならず何らかのクラスから派生する」と定められています。

また、この図で使われている記号などの詳細は、後日掲載するUMLの記事で解説します。

オブジェクト思考の例:人間クラスからJohnSmithオブジェクトを生成する

今回定義するJohnSmithの仮の人物像

今度は人間クラスをもとに、「JohnSmith」(ジョン・スミス)を生成します。

  • 名前:John Smith
  • 性別:男
  • 人種:白色人種
  • 配偶者:なし
定義した人間クラスをもとにJohnSmithを定義した例
定義した人間クラスをもとにJohnSmithを定義した例

なお、挨拶メソッドは人間クラスに定義されているため、ここでは定義不要です。

このように、特定のクラスからオブジェクトを生成することを「インスタンス化」すると言い、クラスからインスタンス化されたオブジェクトのことを「インスタンス」と言います。

 

このJohnSmithインスタンスは、挨拶メソッドを呼びだすと「Hello」と返してくれます。

オブジェクト指向の例:人間クラスからMarySmithインスタンスを生成する

今回定義するMarySmithの仮の人物像

続けて、二人目の人間である「MarySmith」(メアリー・スミス)も生成します。

  • 名前:Mary Smith
  • 性別:女
  • 配偶者:なし

このMarySmithインスタンスもJohnSmith同様に、挨拶メソッドを呼びだすと「Hello」と返します。

オブジェクト思考の例:人間クラスから田中太郎を生成する

今回定義する田中太郎の仮の人物像

次は日本人の田中太郎インスタンスを、人間クラスから生成します。

しかし、これには落とし穴があります。

 

なぜなら今定義した田中太郎に挨拶をさせると、日本人でありながら「Hello」と挨拶をしてしまうからです。

定義した人間クラスをもとにJohnSmithとMarySmithと田中太郎定義した例。田中太郎の実装には不具合がある
定義した人間クラスをもとにJohnSmithとMarySmithと田中太郎定義した例。田中太郎の実装には不具合がある

この問題は、「クラス構造」が不適切だから起こっています。

オブジェクト思考の例:人間クラスを抽象クラス化し、継承する

今回の問題は「人間」という抽象的な概念をそのまま使って、インスタンスを生成したことに起因します。

そこで以下のように構造を変更しましょう。

ここでは人間クラスをまんま使うのをやめて、人間クラスを抽象クラスとして定義しなおします。ここで言う「抽象クラス」とは、そのまま字面通り「抽象的な概念を扱うクラス」のことです。

そして、その抽象クラスを継承した「具象クラス」を定義し、その具象クラスをインスタンス化します。

継承とは、より大きな概念の特徴を引き継いで、より具体的な特徴などを加えてクラスを定義することです。ここでは「人間」という抽象的な概念(≒抽象クラス)のもつ特徴(3つのプロパティと1つのメソッド)を引き継ぎ、より具体的な「アメリカ人」と「日本人」という別のクラス(≒具象クラス)を定義しています。

このようにクラスを継承することで、既存のメソッドの内容を上書きしたり、新しいメソッドやプロパティを追加できます。

 

これにより、アメリカ人クラスのインスタンスであるJohnとMaryは挨拶をさせると「Hello」と言い、太郎に挨拶をさせると「こんにちは」と正しく言えるようになります。

オブジェクト思考の例: JohnSmithとMarySmithが結婚したが、それに嫉妬した田中太郎

では少し応用的な例を考えてみましょう。

今まで作成したMaryとJohnを結婚させ、互いに関係をもたせます。

これは互いの「配偶者プロパティ」に、互いのインスタンスを代入(=参照の代入を)して実現します。

 

しかし太郎はMaryとJohnの結婚に反対で、Maryと結婚したいと考えていました。
そこで太郎は、全員の配偶者プロパティを、無断で強制的に変更してしまいました。

すると、MaryとJohnは破局し、太郎とMaryが婚姻関係をもつようになりました。

これでは大問題です。

現実のプログラミングにおいても、このような例は度々起こります。

今回のように、本来は第三者に変更されてはいけない内容を守る手段が、OOPでは用意されています。

オブジェクト指向の例:婚姻可能インターフェースを定義し婚姻関係を改ざんされなくする

そこで以下のような構造に変更し、このような問題が起こらないようにしょう。


人間クラスに婚姻可能インターフェースを継承させ、配偶者をみだりに第三者に変更されなくした。各々のインスタンス自体が婚姻を申し込まれた相手に「婚姻意思確認」 メソッド の結果を返し、婚姻意思がある場合は自身のみが配偶者を変更する。

この手順を踏めば、本人たちの意思に関係ない、「婚姻関係の改ざん」ができなくなります。

この例は項目が多く理解が大変ですが、今回は厳密に理解する必要はありません。

 

ここでは「婚姻可能インターフェース」というものが、新たに登場したことに気をつけてください。

インターフェースとは、インスタンス化される際に、特定のメソッドの実装を強制する仕組みのことです。具体的には「婚姻意思確認」というメソッドと、「婚姻」メソッドの実装が、アメリカ人クラスと日本人クラスに強制されます。

 

Johnに婚姻を申し込まれたMaryは「婚姻意思確認」メソッドで意思を確認し、婚姻の意志があることを相手に伝えます。そしてMaryは自身の配偶者をJohnに変更します。

婚姻を申し込んだJohnは、Maryに婚姻の意志があることを知り、自身の配偶者をMaryに変更します。

これによってMaryとJohnの婚姻が成立します。
なお、ここでいう婚姻の成立とは「人間クラスの婚姻判定メソッドが、婚姻関係にあると判断したこと」を意味します。

 

では、これが太郎の場合はどうでしょうか。

今回は前回のように、太郎が「直接相手の配偶者を変更すること」ができません。

そこで太郎は、とりあえずMaryに婚姻を申し込みました。Maryは太郎の申し出に対して、「婚姻意思確認」メソッドで婚姻の意志がないことを確認し、太郎へ伝えます。

この時、Maryの配偶者は太郎にはなっていません。

しかし太郎はMaryに婚姻の意志がないことを伝えられても、知らぬ顔をして自身の配偶者をMaryに変更しました。

その後、太郎は意気揚々と人間クラスの婚姻判定で二人の関係を調べましたが、その結果は未婚状態のままでした。

なぜなら太郎にはMaryの配偶者を変更する手段も、人間クラスの婚姻判定メソッドを変える手段もないためです。

ガチャガチャのカプセル

このように、「プロパティやメソッドの一部を非公開にすること」を「カプセル化」といいます。カプセル化はオブジェクト思考の重要な機能と言えます。

また、この例は「ポリモフィズム」(多態性)をインターフェースで実現した例になっています。ポリモフィズムもOOPの重要な役割ですが、こちらは初心者泣かせなので別の記事で解説します。

まとめ

まとめ

今回の記事は非常に専門的な内容となりました。とはいえ扱った内容自体は簡単だったので、何度か読みかえすことで理解できた方は多いでしょう。

今回扱ったオブジェクト指向プログラミングの要点を整理すると、以下のようになります。

  • オブジェクト思考とは、オブジェクト指向プログラミング(Object-Oriented-Programming)のことを指し、OOPと略す
  • オブジェクトはかならずクラスにより生成される
  • オブジェクトは属性(プロパティ)と能力(メソッド)の2つ要素で構成される
  • クラスからオブジェクトを生成することを「インスタンス化する」と言い、この時のオブジェクトを「インスタンス」と言う
  • クラスを使えばさまざまなインスタンスを簡単に生成できる
  • しかしクラス構造を誤ると、誤作動することがある
  • 抽象的な概念は抽象クラスを用い、それを継承した具体的な内容は具象クラスをインスタンス化して使う
  • OOPではカプセル化によって、プログラムによる誤った修正などを防げる

OOPは、これからエンジニアを目指す方や、現役のエンジニアの方には避けて通ることができないほどに重要です。

そして、これらは専門用語が多く難解です。

皆さんがいざという時にでも、この記事を読み直して頂ければと思います。

よく読まれている記事

1

21世紀の現在、ネット上では掲示板やアンケートフォームと言った一見簡単に見えるサービス機能から、商品カタログ、eコマースなどのスケールの大きなコンテンツまで、様々なダイナミックコンテンツが普及するよう ...

2

テクノロジーの進化により今後10年で50%以上の仕事がなくなると言われています。 それは現在の仕事がプログラムに取って代わられることを意味します。 今後「プログラミング」は「文字」と同様に「一般教養」 ...

3

2019年、出生数は過去最小の86万4千人!推計より2年早く、初めての90万人割れ日本の経済成長(2019年10~12月期の実質GDP)は、年率6.3%減! コロナウィルスとは関係なく急落しています。 ...

4

ITエンジニア転職に必要な知識として一番最初に挙げられるのは「プログラミング」の知識でしょう。 20代、30代であれば確かにそれは正しいと言えます。 しかし、40代、50代を対象にした場合、果たして「 ...

5

ここ数年、メディアなどでフリーランスという言葉を耳する機会が増え、それに比例するようにフリーランスを志す人が急増しています。 テクノロジーの進歩により、個人単位でのロケーションにとらわれないスタイルで ...

6

人口知能や機械学習というキーワードは、IT業界で働く人にとっては馴染みが深くなりつつあります。 これらを駆使するAIエンジニアには高いスキルが要求され、日本だけでなく世界的に見ても不足している状況です ...

-エンジニアの知識

Copyright© Beエンジニア , 2020 All Rights Reserved.