どーもー、現在某IT系の会社でjavaエンジニアとして働ている者です。(当ブログの管理人です)
エンジニアやプログラマーとして働いている方はもちろん、javaやPHP、Rubyなど、何かしらのプログラミング言語を学んでいる方であれば、必須の知識として理解しておくべき
「オブジェクト指向プログラミング(OOP:object oriented programming)」
とはいえ、意外と聞いたことあるけど、「イマイチ、理解できてない」・「なんとなく、分かる程度」といった方も多いと思います。
というわけで、今回はこの「オブジェクト指向」について、その概念・仕組みから、メリット・デメリット。
javaプログラムでの例題を交えた解説までをしていきたいと思います。
※例題はjavaですが、javaを使った事が無い方でも、理解できるような内容にしています。
開発現場やプログラミング業界では、「知っていて、当たり前の概念」なので、ぜひ、当記事を読み進めていって、理解していただければと思います。
以下、目次。
- オブジェクト指向とは?OOP(object oriented programming)の基本概念について分かりやすく解説
- なぜ、オブジェクト指向でプログラムを作るのか? ~メリット・デメリットのまとめ
- 代表的なオブジェクト指向型プログラミング言語:「java」の例題を交えて分かりやすく解説
オブジェクト指向とは?OOP(object oriented programming)の基本概念について分かりやすく解説
ではまず、オブジェクト指向の基本概念について。
というプログラミングしていく上での考え方の事です。
要は、多数の部品(オブジェクト)の集合体が、一つのシステム(プログラム)として構成されている。といったイメージですね。
オブジェクトとは、直訳すると、「物」や「対象物」といった意味になりますが、プログラミング視点でのオブジェクトは、「データ(プロパティ)と、機能(役割)の集合体」として定義できます。
一つ、例を出してみましょう。
「人間」を、プログラミング上のオブジェクトとして作成するとしたら、
人間(オブジェクト)
「データ(プロパティ、属性)」 : 年齢、住んでいる場所、身長、体重、好きな食べ物、etc
「機能(役割、振る舞い)」 : 話す、寝る、好きな物を食べる、(住んでいる場所に)帰宅する、etc
なんとなく、イメージできましたでしょうか。
これらのオブジェクトを、何百・何千と作成していき、オブジェクト同士の関係性を定義しながら、プログラミングしていくことを、「オブジェクト指向」というわけですね。
ちなみに、「オブジェクト指向」という言葉が誕生したのは、今から50年くらい前で、1970年代に誕生したそうです。
「パーソナルコンピュータの父」と言われる、アラン・ケイと呼ばれる業界では有名な人が作ったとされ、1981年頃から知名度を得て、90年代には、プログラミングやソフトウェア開発をする上での、標準的な基本概念として確立したそうです。
・
・
・
次に、プログラミング言語というのは、大きく以下2つに切り分けることができます。
・手続き型言語 : C言語、COBOLなど
・オブジェクト指向言語 : Java、PHP、Ruby、Pythonなど
オブジェクト指向言語については上述の通りですが、一方の「手続き型言語」というのは、プログラムが動作する内容を、一から順々に(上から下へ流れるように)書いていくプログラミング手法となります。
というわけで、この「手続き型言語」と比較して、「オブジェクト指向言語」には、どのようなメリット・デメリットがあるのか・・・
次の章にてまとめていきたいと思います。
なぜ、オブジェクト指向でプログラムを作るのか? ~メリット・デメリットのまとめ
まずは、(手続き型言語と比較して)オブジェクト指向でプログラミングする際のメリットについて、以下にまとめていきます。
-
「カスタマイズや再利用がしやすく、プログラミングの効率性が高い」
こちらが、オブジェクト指向でプログラミングする際の、最も重要なメリットと言えるでしょう。
オブジェクト指向で開発されたプログラムは、カスタマイズや再利用がしやすいというメリットがあり、これが、プログラミング作業の大幅な効率化に繋がります。
具体例を交えて説明します。
上述でも例に挙げた、「人間」を、プログラミング上のオブジェクトとして作成する場合、
「データ(プロパティ)」 : 名前、年齢、住所、好きな食べ物、etc
「機能(役割)」 : 話す、寝る、食べる、etc
上記のようなデータと機能を定義した「人間オブジェクト」を元に、100人の「人間」を作成するとします。
この時、「手続き型プログラミング」であれば、1~100人分、一人一人の人間オブジェクトを順に作成する必要があります。
ですが、「オブジェクト指向プログラミング」であれば、最初に、基本となる「人間」という型(クラス)を作成しておけば、
あとは、その型(クラス)を「継承」さえすれば、100人分の「人間オブジェクト」を、一人一人作成する必要が無くなります。
※型(クラス)とは、オブジェクトを作成する際の元となるモノであり、クラス(型)を元にオブジェクトは作成されます。
例えば、上述のオブジェクトを構成する「データ」と「機能」についてですが、「人間」には誰だって、名前や年齢、住所の情報を持ってますし、誰だって、話したり・寝たり・食べたり・・・できますよね。
このように、共通となる部分を、最初に一つ作成しておけば、100人分のオブジェクトを作成するってなっても、共通部分については、1つ1つ作成しなくても良くなるわけです。
これが、オブジェクト指向の最も重要なメリットである「再利用性」であり、共通部分のプログラムを一つにまとめて、それを再利用することを「継承」と言います。
逆に以下の通り、共通部分についても、一つ一つの「人間オブジェクト」に作成していかないといけないのが、「手続き型プログラミング」になります。
・
・
・また、100人分の人間オブジェクトを作成したあとに、「走る」という機能を追加したくなった場合・・・
オブジェクト指向であれば、共通部分に、機能追加するだけで良いのですが、手続き型プログラミングの場合は、100人分一人一人のプログラムに機能追加する必要が出てきます。
このように、出来上がったプログラムに対して、何かしらの修正や機能追加が必要になった場合の、開発効率の高さも、オブジェクト指向のメリットとなります。
違いは、一目瞭然ですよね。
-
「大人数でのチーム開発に向いている」
上記のメリットにも関係してきますが、オブジェクト指向プログラミングは、大人数での開発に向いていると言われています。
それは、プログラムを各部品化(オブジェクト化)させることによって、部品ごとの機能や役割を、開発者同士で共有・連携がしやすくなったり、分担作業にも向いています。
逆に、手続き型言語の場合は、上から下に流れるようにプログラムが構成されており、オブジェクト指向のようにプログラムの「まとまり」が薄いため、その分、チーム内で共有・連携がしにくかったり、分担作業がやりにくい。。といった特徴があります。
また、オブジェクト指向の場合は、上述の通り、再利用性が高い共通部品を誰かが作成しておけば、他のメンバーは、それを利用すれば良いだけになるので、チーム全体の開発の効率化に繋がるでしょう。
ただし、大規模なシステムであれば、何千・何万というオブジェクト(部品)で構成される事になるため、システム全体の構成を把握するのに、かなり時間が掛かってしまうデメリットもあります。(手続き型言語と比較して・・) -
「不具合の原因を特定がしやすい」
これについても、上述で記載してきた事に関係してくるポイントになりますが、
オブジェクト指向によって、プログラムが各部品化されており、各部品の機能や役割も明確になっています。
なので、仮にプログラム内でエラーが起きたとしても、「どこでエラーが発生したのか?」といった事を判断しやすく、調査や保守がしやすいのもメリットの一つとなっています。
逆に、手続き型言語の場合は、上から下に流れるようにプログラムが構成されており、機能や役割ごとにプログラムが分かれている訳では無いので、エラーの原因の特定に時間が掛かったり、同じようなエラーが、プログラムのあっちこっちに点在したりするので、保守・管理するのも大変となります。
オブジェクト指向でプログラミングされたシステムであれば、機能や役割ごとにプログラム(オブジェクト)がきっちりと区別されているため、エラーの原因となったプログラムが、あっちこっちに点在することは基本的にありません。
なので、一か所を修正すれば、それでシステム全体からエラーを取り除くことができるわけですね。
以上が、オブジェクト指向プログラミングのメリットになります。
・
・
・
続いて、デメリットについても以下にまとめていきましょう。
-
「システムの全体像を理解するのが難しい。。。」
オブジェクト指向の場合、システムが大規模であればあるほど、何万・何十万といったオブジェクト(部品)で構成される事になるため、システム全体の構成を把握するのに、かなり時間が掛かってしまうデメリットがあります。
逆に、手続き型言語の場合は、プログラムが上から下に順に構成されていっているため、構成自体は単純なものとなります。
そのため、プログラムが記載された順に読む進めていけば良く、システム全体の理解のしやすさ。といった点では、手続き型言語の方が上でしょう。
このように、プログラムが全体でみれば複雑になりやすいのが、オブジェクト指向の特徴になります。
-
「システムの設計作業が難しいし、設計に失敗すると・・・」
何かしらのプログラム(システム)を作成する。ってなった場合、工程的にまず最初におこなうのが、設計作業になります。
設計が終わったら、その設計内容を元に、プログラマーがプログラミングしていく。といった流れが、一般的な開発現場ですからね。
で、オブジェクト指向の場合、この設計作業が非常に重要で、かつ難しい作業となります。(システムが複雑であればあるほど)
・システムを構成する上で、どのような部品(オブジェクト)が必要となり、部品同士の関係性をどのように定義するか。・データや機能が被っている部品が無いか。
・チームのメンバーが分担して開発しやすいような構成になっているか。
・また、各部品が共通で利用できそうなデータや機能は無いか。そして、共通で利用する部品を作成した時に、再利用やカスタマイズはしやすくなるのか。
等々、保守や調査・カスタマイズのしやすさ等、将来的な事までちゃんと考えた上で、設計する必要があります。
そして、この設計作業に失敗してしまうと、
本来、システムを構成する各部品(オブジェクト)には、明確な機能や役割を定義しなければいけないのに、そこが分かりづらくて、理解が困難なプログラムになったり、間違った(部品の)使い方をしてしまい、思わぬエラーになったり、
データや機能が多数被っている部分があり、それが原因となって、調査やカスタマイズに大幅な時間が掛かったり、エラーが頻発したり、、
こんな悲惨な事になってしまいます。
なので、オブジェクト指向でシステム設計を一からする場合には、様々な観点で物事を考えられて、これまでにも同じようなシステム設計の経験があるような、熟練した方が担当する必要があるでしょう。
以上、オブジェクト指向プログラミングのデメリットまとめでした。
オブジェクト指向プログラミングに関連するキーワードを分かりやすくまとめてみました。
続いて、上述でも何度か頻出していますが、オブジェクト指向を学んでいく上で、よく出る関連用語や、知っておいたほうが良いキーワードを解説していきます。
-
「オブジェクト」
オブジェクトについては、上述でも解説しているので、大丈夫かと思います。
直訳すると、「モノ」・「対象物」といった意味を持ちますが、プログラミングにおいては、上図の通り、データと機能の集合体を意味します。
-
「クラス」
上図の通り、オブジェクトの元となるモノになります。
クラスに定義された情報を元に、オブジェクトが作成されるため、「設計図」のようなイメージになりますね。
オブジェクトと同様に、データと機能の集合体として定義されますが、上図の通り、具体的な車種や大きさ、色などが定義された方が、オブジェクト(インスタンス)になります。
実際に、Javaなどのオブジェクト指向言語にてプログラミングする際は、この「クラス」の作成を基本として、開発していくことになります。(最後の章にて、実際にJavaプログラムを例に解説しているので、ぜひ参考にしてください。)
-
「インスタンス」
上記の「クラス」を元に作成されるのが、インスタンスであり、オブジェクトと同じ認識で良いでしょう。
-
「データ(属性・プロパティ)」
オブジェクトを構成する一つの要素となります。
データ、属性、プロパティなどと呼ばれています。
上図の車のオブジェクトであれば、「車種」や「大きさ」・「色」が該当します。
-
「機能(メソッド、振る舞い、役割)」
こちらも、オブジェクトを構成する、もう一つの要素ですね。
呼び方は、機能、メソッド、振る舞い。など複数あります。
上図の車のオブジェクトであれば、「走る」や「バックする」が該当します。
-
「継承」
こちらも、上述にて解説していますが、オブジェクト指向の最も重要な特徴として挙げられる「再利用性」を実現するための仕組みです。
上図をみればイメージできるかと思いますが、共通で利用したいクラスのデータや機能を引き継ぐことを意味します。
-
「その他」
オブジェクト指向を学んでいく上で、「カプセル化」や「ポリモーフィズム」といった言葉もよく出てきますが、
これらについては、実際にプログラミングをやりながら学んでいけば良いです。(実際にプログラミングをしていないと、イメージしずらい概念になるので。。)
なので、ここでの説明は割愛します。
「なんか聞いたことある、、」くらいの認識で、今はOKです。
以上、オブジェクト指向の関連用語まとめでした。
代表的なオブジェクト指向型プログラミング言語「java」の例題を交えて分かりやすく解説
最後に、オブジェクト指向言語の中でも昔から有名でシェアも高い「java」を用いて、実際にプログラミング例題を交えて、解説していこうと思います。
※javaを知らない人でも、分かるように解説していくので安心してください。
※javaについて知りたい方は以下の記事を参考にしてください。
→ Javaとは?プログラミング言語の特徴や歴史、人気な3つの理由をわかりやすく解説!
今回の例題でやりたいことは、
- 共通で利用する「人間クラス」の作成
- 「人間クラス」を継承するAさんとBさんのクラスを作成
- AさんとBさんのインスタンス(オブジェクト)を作成して、二人に処理(話す、寝る)をさせる、動作確認用のメインクラスを作成
というわけで、さっそくjavaプログラムを以下に作成してみました。
//1、共通で利用する「人間」クラス
public class Human {
//データ(プロパティ)一覧
public String name; //名前
public int age; //年齢
public String address; //住所
public String likeFood; //好きな食べ物
//機能(メソッド)一覧
public void talk(){} //話す
public void sleep(){} //寝る
public void eat(){} //食べる
}
//2、Humanクラスを継承する「Aさん」クラス
public class Aさん extends Human {
//独自のデータ
private String likeGame; //好きなゲーム
//コンストラクタ(インスタンス化するための処理)
public Aさん(String name,int age,String address,String likeFood,String likeGame){
this.name = name;
this.age = age;
this.address = address;
this.likeFood = likeFood;
this.likeGame = likeGame;
}
//独自の機能
public void run(){} //走る
}
//3、Humanクラスを継承する「Bさん」クラス
public class Bさん extends Human {
//独自のデータ
private String likePlace; //好きな場所
//コンストラクタ(インスタンス化するための処理)
public Bさん(String name,int age,String address,String likeFood,String likePlace){
this.name = name;
this.age = age;
this.address = address;
this.likeFood = likeFood;
this.likePlace = likePlace;
}
//独自の機能
public void smile(){} //笑う
}
//4、AさんとBさんのインスタンス(オブジェクト)を作成して、二人に処理(話す&寝る)をさせる動作確認用のクラス
public class Main {
public static void main(){
Human Aさん = new Aさん("A",20,"東京都渋谷区","肉","ドラクエ");
Human Bさん = new Bさん("A",25,"東京都新宿区","魚","秋葉原");
A.talk();
B.sleep();
}
}
以上、動作確認用のクラスを含めて、4つのクラスを作成しました。
上記のjavaプログラムを見るだけでも、「何をやっているのか・・」は、大体理解できたのではないでしょうか。
では、各クラスの内容について、解説していきます。
-
「Humanクラス」
こちらが、共通で利用する「人間」クラスになります。
データ(プロパティ)に、「名前、年齢、住所、好きな食べ物」を定義して、
機能(メソッド)に、「話す、寝る、食べる」を定義しています。
-
「Aさんと、Bさんのクラス」
この2つのクラスは、Humanクラスを継承しているため、Humanクラスで定義しているデータやメソッドを利用することができます。
さらに、それぞれに、独自で利用できるデータと機能も追加しています。
また、「コンストラクタ」と記載されている部分がありますが、これが、インスタンス化(オブジェクトの作成)をする処理となります。
このコンストラクトを通して、2人のオブジェクトを作成するわけですね。
-
「メインクラス」
こちらが、他のクラスを呼び出す動作確認用のメインクラスとなります。
AさんとBさんのオブジェクト(インスタンス)を作成して、話したり、眠らせたり、していますね。
というわけで、それぞれのクラスがどのような事をやっていて、どのような役割を持っているか・・・ある程度理解できたかと思います。
今回は、javaプログラムの細かい部分の理解はしなくて良いので、「4つのクラスで何をしているのか」が大体分かれば、OKです。
というわけで、ここまで実際にjavaプログラムの例題も交えて、オブジェクト指向がどういったモノなのか。を、一から解説してきました。
ここまで読んでいただけた方が、オブジェクト指向について理解できていたら幸いです。