オブジェクト指向プログラミングとは

オブジェクト指向とは?プログラミングする上でのメリットや、java言語での例題を交えて分かりやすく解説


どーもー、現在某IT系の会社でjavaエンジニアとして働ている者です。(当ブログの管理人です)

エンジニアやプログラマーとして働いている方はもちろん、javaやPHP、Rubyなど、何かしらのプログラミング言語を学んでいる方であれば、必須の知識として理解しておくべき

「オブジェクト指向プログラミング(OOP:object oriented programming)」

とはいえ、意外と聞いたことあるけど、「イマイチ、理解できてない」・「なんとなく、分かる程度」といった方も多いと思います。

というわけで、今回はこの「オブジェクト指向」について、その概念・仕組みから、メリット・デメリット。

javaプログラムでの例題を交えた解説までをしていきたいと思います。

※例題はjavaですが、javaを使った事が無い方でも、理解できるような内容にしています。

開発現場やプログラミング業界では、「知っていて、当たり前の概念」なので、ぜひ、当記事を読み進めていって、理解していただければと思います。

以下、目次。

  1. オブジェクト指向とは?OOP(object oriented programming)の基本概念について分かりやすく解説
  2. なぜ、オブジェクト指向でプログラムを作るのか? ~メリット・デメリットのまとめ
  3. 代表的なオブジェクト指向型プログラミング言語:「java」の例題を交えて分かりやすく解説

オブジェクト指向とは?OOP(object oriented programming)の基本概念について分かりやすく解説

オブジェクト指向の基本概念とは-4

ではまず、オブジェクト指向の基本概念について。

オブジェクト指向とは・・・プログラミングする上での考え方(概念)で、システムを構成する膨大なプログラムを、「とある役割を持った部品(オブジェクト(又はクラス)と呼ぶ)」単位で分割していき、それらの部品と部品の関係性を定義していくことで、システム(プログラム)を構築していく。

というプログラミングしていく上での考え方の事です。

要は、多数の部品(オブジェクト)の集合体が、一つのシステム(プログラム)として構成されている。といったイメージですね。

オブジェクトとは、直訳すると、「物」や「対象物」といった意味になりますが、プログラミング視点でのオブジェクトは、「データ(プロパティ)と、機能(役割)の集合体」として定義できます。

一つ、例を出してみましょう。

「人間」を、プログラミング上のオブジェクトとして作成するとしたら、

人間(オブジェクト)

「データ(プロパティ、属性)」 : 年齢、住んでいる場所、身長、体重、好きな食べ物、etc

「機能(役割、振る舞い)」 : 話す、寝る、好きな物を食べる、(住んでいる場所に)帰宅する、etc

なんとなく、イメージできましたでしょうか。

これらのオブジェクトを、何百・何千と作成していき、オブジェクト同士の関係性を定義しながら、プログラミングしていくことを、「オブジェクト指向」というわけですね。

ちなみに、「オブジェクト指向」という言葉が誕生したのは、今から50年くらい前で、1970年代に誕生したそうです。

「パーソナルコンピュータの父」と言われる、アラン・ケイと呼ばれる業界では有名な人が作ったとされ、1981年頃から知名度を得て、90年代には、プログラミングやソフトウェア開発をする上での、標準的な基本概念として確立したそうです。

参考:ウィキペディア:オブジェクト指向



次に、プログラミング言語というのは、大きく以下2つに切り分けることができます。

・手続き型言語 : C言語、COBOLなど

・オブジェクト指向言語 : Java、PHP、Ruby、Pythonなど

オブジェクト指向言語については上述の通りですが、一方の「手続き型言語」というのは、プログラムが動作する内容を、一から順々に(上から下へ流れるように)書いていくプログラミング手法となります。

というわけで、この「手続き型言語」と比較して、「オブジェクト指向言語」には、どのようなメリット・デメリットがあるのか・・・

次の章にてまとめていきたいと思います。

なぜ、オブジェクト指向でプログラムを作るのか? ~メリット・デメリットのまとめ

まずは、(手続き型言語と比較して)オブジェクト指向でプログラミングする際のメリットについて、以下にまとめていきます。

  1. 「カスタマイズや再利用がしやすく、プログラミングの効率性が高い」

    こちらが、オブジェクト指向でプログラミングする際の、最も重要なメリットと言えるでしょう。

    オブジェクト指向で開発されたプログラムは、カスタマイズや再利用がしやすいというメリットがあり、これが、プログラミング作業の大幅な効率化に繋がります。

    具体例を交えて説明します。

    上述でも例に挙げた、「人間」を、プログラミング上のオブジェクトとして作成する場合、

    「データ(プロパティ)」 : 名前、年齢、住所、好きな食べ物、etc

    「機能(役割)」 : 話す、寝る、食べる、etc

    上記のようなデータと機能を定義した「人間オブジェクト」を元に、100人の「人間」を作成するとします。

    この時、「手続き型プログラミング」であれば、1~100人分、一人一人の人間オブジェクトを順に作成する必要があります。

    ですが、「オブジェクト指向プログラミング」であれば、最初に、基本となる「人間」という型(クラス)を作成しておけば、

    あとは、その型(クラス)を「継承」さえすれば、100人分の「人間オブジェクト」を、一人一人作成する必要が無くなります。

    ※型(クラス)とは、オブジェクトを作成する際の元となるモノであり、クラス(型)を元にオブジェクトは作成されます。

    オブジェクト指向の概念イメージ-1

    例えば、上述のオブジェクトを構成する「データ」と「機能」についてですが、「人間」には誰だって、名前や年齢、住所の情報を持ってますし、誰だって、話したり・寝たり・食べたり・・・できますよね。

    このように、共通となる部分を、最初に一つ作成しておけば、100人分のオブジェクトを作成するってなっても、共通部分については、1つ1つ作成しなくても良くなるわけです。

    これが、オブジェクト指向の最も重要なメリットである「再利用性」であり、共通部分のプログラムを一つにまとめて、それを再利用することを「継承」と言います。

    逆に以下の通り、共通部分についても、一つ一つの「人間オブジェクト」に作成していかないといけないのが、「手続き型プログラミング」になります。

    手続き型プログラミングのイメージ-1



    また、100人分の人間オブジェクトを作成したあとに、「走る」という機能を追加したくなった場合・・・

    オブジェクト指向であれば、共通部分に、機能追加するだけで良いのですが、手続き型プログラミングの場合は、100人分一人一人のプログラムに機能追加する必要が出てきます。

    このように、出来上がったプログラムに対して、何かしらの修正や機能追加が必要になった場合の、開発効率の高さも、オブジェクト指向のメリットとなります。

    違いは、一目瞭然ですよね。

  2. 「大人数でのチーム開発に向いている」

    上記のメリットにも関係してきますが、オブジェクト指向プログラミングは、大人数での開発に向いていると言われています。

    それは、プログラムを各部品化(オブジェクト化)させることによって、部品ごとの機能や役割を、開発者同士で共有・連携がしやすくなったり、分担作業にも向いています。

    逆に、手続き型言語の場合は、上から下に流れるようにプログラムが構成されており、オブジェクト指向のようにプログラムの「まとまり」が薄いため、その分、チーム内で共有・連携がしにくかったり、分担作業がやりにくい。。といった特徴があります。

    また、オブジェクト指向の場合は、上述の通り、再利用性が高い共通部品を誰かが作成しておけば、他のメンバーは、それを利用すれば良いだけになるので、チーム全体の開発の効率化に繋がるでしょう。

    ただし、大規模なシステムであれば、何千・何万というオブジェクト(部品)で構成される事になるため、システム全体の構成を把握するのに、かなり時間が掛かってしまうデメリットもあります。(手続き型言語と比較して・・)
  3. 「不具合の原因を特定がしやすい」

    これについても、上述で記載してきた事に関係してくるポイントになりますが、

    オブジェクト指向によって、プログラムが各部品化されており、各部品の機能や役割も明確になっています。

    なので、仮にプログラム内でエラーが起きたとしても、「どこでエラーが発生したのか?」といった事を判断しやすく、調査や保守がしやすいのもメリットの一つとなっています。

    逆に、手続き型言語の場合は、上から下に流れるようにプログラムが構成されており、機能や役割ごとにプログラムが分かれている訳では無いので、エラーの原因の特定に時間が掛かったり、同じようなエラーが、プログラムのあっちこっちに点在したりするので、保守・管理するのも大変となります。

    オブジェクト指向でプログラミングされたシステムであれば、機能や役割ごとにプログラム(オブジェクト)がきっちりと区別されているため、エラーの原因となったプログラムが、あっちこっちに点在することは基本的にありません。

    なので、一か所を修正すれば、それでシステム全体からエラーを取り除くことができるわけですね。

以上が、オブジェクト指向プログラミングのメリットになります。




続いて、デメリットについても以下にまとめていきましょう。

  1. 「システムの全体像を理解するのが難しい。。。」

    オブジェクト指向の場合、システムが大規模であればあるほど、何万・何十万といったオブジェクト(部品)で構成される事になるため、システム全体の構成を把握するのに、かなり時間が掛かってしまうデメリットがあります。

    逆に、手続き型言語の場合は、プログラムが上から下に順に構成されていっているため、構成自体は単純なものとなります。

    そのため、プログラムが記載された順に読む進めていけば良く、システム全体の理解のしやすさ。といった点では、手続き型言語の方が上でしょう。

    このように、プログラムが全体でみれば複雑になりやすいのが、オブジェクト指向の特徴になります。

  2. 「システムの設計作業が難しいし、設計に失敗すると・・・」

    何かしらのプログラム(システム)を作成する。ってなった場合、工程的にまず最初におこなうのが、設計作業になります。

    設計が終わったら、その設計内容を元に、プログラマーがプログラミングしていく。といった流れが、一般的な開発現場ですからね。

    で、オブジェクト指向の場合、この設計作業が非常に重要で、かつ難しい作業となります。(システムが複雑であればあるほど)

    ・システムを構成する上で、どのような部品(オブジェクト)が必要となり、部品同士の関係性をどのように定義するか。

    ・データや機能が被っている部品が無いか。

    ・チームのメンバーが分担して開発しやすいような構成になっているか。

    ・また、各部品が共通で利用できそうなデータや機能は無いか。そして、共通で利用する部品を作成した時に、再利用やカスタマイズはしやすくなるのか。

    等々、保守や調査・カスタマイズのしやすさ等、将来的な事までちゃんと考えた上で、設計する必要があります。

    そして、この設計作業に失敗してしまうと、

    本来、システムを構成する各部品(オブジェクト)には、明確な機能や役割を定義しなければいけないのに、そこが分かりづらくて、理解が困難なプログラムになったり、間違った(部品の)使い方をしてしまい、思わぬエラーになったり、

    データや機能が多数被っている部分があり、それが原因となって、調査やカスタマイズに大幅な時間が掛かったり、エラーが頻発したり、、

    こんな悲惨な事になってしまいます。

    なので、オブジェクト指向でシステム設計を一からする場合には、様々な観点で物事を考えられて、これまでにも同じようなシステム設計の経験があるような、熟練した方が担当する必要があるでしょう。

以上、オブジェクト指向プログラミングのデメリットまとめでした。

オブジェクト指向プログラミングに関連するキーワードを分かりやすくまとめてみました。

続いて、上述でも何度か頻出していますが、オブジェクト指向を学んでいく上で、よく出る関連用語や、知っておいたほうが良いキーワードを解説していきます。

  1. 「オブジェクト」

    オブジェクトの概念図-2

    オブジェクトについては、上述でも解説しているので、大丈夫かと思います。

    直訳すると、「モノ」・「対象物」といった意味を持ちますが、プログラミングにおいては、上図の通り、データと機能の集合体を意味します。

  2. 「クラス」

    クラスとインスタンス(オブジェクト)の概念図-3

    上図の通り、オブジェクトの元となるモノになります。

    クラスに定義された情報を元に、オブジェクトが作成されるため、「設計図」のようなイメージになりますね。

    オブジェクトと同様に、データと機能の集合体として定義されますが、上図の通り、具体的な車種や大きさ、色などが定義された方が、オブジェクト(インスタンス)になります。

    実際に、Javaなどのオブジェクト指向言語にてプログラミングする際は、この「クラス」の作成を基本として、開発していくことになります。(最後の章にて、実際にJavaプログラムを例に解説しているので、ぜひ参考にしてください。)

  3. 「インスタンス」

    上記の「クラス」を元に作成されるのが、インスタンスであり、オブジェクトと同じ認識で良いでしょう。

  4. 「データ(属性・プロパティ)」

    オブジェクトを構成する一つの要素となります。

    データ、属性、プロパティなどと呼ばれています。

    上図の車のオブジェクトであれば、「車種」や「大きさ」・「色」が該当します。

  5. 「機能(メソッド、振る舞い、役割)」

    こちらも、オブジェクトを構成する、もう一つの要素ですね。

    呼び方は、機能、メソッド、振る舞い。など複数あります。

    上図の車のオブジェクトであれば、「走る」や「バックする」が該当します。

  6. 「継承」

    オブジェクト指向の継承-1

    こちらも、上述にて解説していますが、オブジェクト指向の最も重要な特徴として挙げられる「再利用性」を実現するための仕組みです。

    上図をみればイメージできるかと思いますが、共通で利用したいクラスのデータや機能を引き継ぐことを意味します。

  7. 「その他」

    オブジェクト指向を学んでいく上で、「カプセル化」や「ポリモーフィズム」といった言葉もよく出てきますが、

    これらについては、実際にプログラミングをやりながら学んでいけば良いです。(実際にプログラミングをしていないと、イメージしずらい概念になるので。。)

    なので、ここでの説明は割愛します。

    「なんか聞いたことある、、」くらいの認識で、今はOKです。

以上、オブジェクト指向の関連用語まとめでした。

代表的なオブジェクト指向型プログラミング言語「java」の例題を交えて分かりやすく解説

オブジェクト指向型プログラミング言語:java-1

最後に、オブジェクト指向言語の中でも昔から有名でシェアも高い「java」を用いて、実際にプログラミング例題を交えて、解説していこうと思います。

※javaを知らない人でも、分かるように解説していくので安心してください。

※javaについて知りたい方は以下の記事を参考にしてください。

→ Javaとは?プログラミング言語の特徴や歴史、人気な3つの理由をわかりやすく解説!

今回の例題でやりたいことは、

  1. 共通で利用する「人間クラス」の作成
  2. 「人間クラス」を継承するAさんとBさんのクラスを作成
  3. 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プログラムの例題も交えて、オブジェクト指向がどういったモノなのか。を、一から解説してきました。

ここまで読んでいただけた方が、オブジェクト指向について理解できていたら幸いです。


コメントを残す

メールアドレスが公開されることはありません。