徹底解説!オブジェクト指向とは【初心者向け】
初心者向けにプログラミングにおけるオブジェクト指向とは何か詳しく解説しています。プログラミング言語を理解する上でオブジェクト指向という言葉はよく出てきます。概念として理解しておくと言語自体の習得もスムーズなので、ぜひ覚えておきましょう。
テックアカデミーマガジンは受講者数No.1のプログラミングスクール「テックアカデミー」が運営。初心者向けにプロが解説した記事を公開中。現役エンジニアの方はこちらをご覧ください。 ※ アンケートモニター提供元:GMOリサーチ株式会社 調査期間:2021年8月12日~8月16日 調査対象:2020年8月以降にプログラミングスクールを受講した18~80歳の男女1,000名 調査手法:インターネット調査
プログラミング言語を学習する中でオブジェクト指向という言葉を聞いたことがある人は多いのではないでしょうか。
この記事では、オブジェクト指向という概念について解説します。
なお本記事は、TechAcademyのJava講座の内容をもとに作成しています。
ここではオブジェクト指向について詳しく見ていこうか。
田島メンター!Javaはオブジェクト指向の言語なんですよね。まだあまり把握できていないのですが、一体どういうものなんでしょうか~?
そうだね、まずはどういった背景でオブジェクト指向が生まれたのかというところから話をしよう。
はい!よろしくお願いします!
オブジェクト指向とは
オブジェクト指向(Object-Oriented)という言葉は、現代のプログラミングにとって馴染みの深い用語でありながら、その全容を正しく理解することは困難を極めます。
その原因の一つに、この言葉の成り立ちが複数の異なる概念からスタートしていることが挙げられます。
クラスやオブジェクトという言葉が生まれたのは、1960年代後半に開発されたSimula67というプログラミング言語です。とはいえ、この時点ではオブジェクト指向という考え方は存在していませんでした。
このSimula67のオブジェクトを用いて、コンピューティングをオブジェクトとそれに対するメッセージングで表現するという考えをアラン・ケイが提唱し、この考え方をオブジェクト指向(Object-Oriented)と名付けました。この考えでは、オブジェクトではなくメッセージのやりとりこそが重要な点であると主張されています。
一方で、ビャーネ・ストラウストラップは、Simula67のクラスを用いることで、int型のようなデータ型をユーザーが新しく定義できることに着目しました。このようなユーザー定義のデータ型は抽象データ型と呼ばれます。
この思想はバーバラ・リスコフが開発したプログラミング言語CLUを経てC++などの言語に取り入れられ、カプセル化や継承、多態性といった要素を含む現在のオブジェクト指向の根幹となっています。
このように、概念の異なる複数の思想がともにオブジェクト指向という名で呼ばれるようになりました。その後、多くのオブジェクト指向言語が開発され、実用される中で、オブジェクト指向プログラミングのサンプルは非常に増えましたが、オブジェクト指向とは何かを一言で定義することは難しくなっています。
この記事では、ストラウストラップらによる、抽象データ型の実現という側面から見たオブジェクト指向について解説します。この考えはクラスベースのオブジェクト指向とも呼ばれます。
クラスベースのオブジェクト指向
抽象データ型は、以下のような特徴を持っています。
- データ構造とそれに対する手続きが定義されている
- intのようなプリミティブ型と同様にデータ型として使用できる
クラスベースのオブジェクト指向では、データ構造(フィールド)と手続き(メソッド)を持つクラスを定義し、変数やメソッド引数・戻り値の型として使用することができます。これは、抽象データ型を実現したものとなります。
例として、Java言語でよく使用するStringもそうしてデータ構造と手続きを定義されたクラスです。Stringはintのようなプリミティブ型と同様にデータ型として使用でき、参照型と呼ばれます。
int i = 0; // プリミティブ型 String s = "Hello, World"; // Stringクラスとして定義された参照型
ここで、上記の変数sは、Stringクラス内に定義されたデータ構造を使用して”Hello, World”という文字列を保持しています。
また、例えば文字列の文字数が知りたい場合に、以下のようにメソッドを呼び出すことで、手続きを行うことができます。
String s = "Hello, World"; int count = s.length(); // lengthメソッドの呼び出し
このとき、lengthメソッドを呼び出す側は、Stringクラス内に文字列がどのようなデータ構造として格納されているか、ということを知る必要はありません。Stringクラス内部のデータ構造に直接アクセスすることなく、手続きとしてのメソッドを呼び出すことで文字数を取得するという目的が達成できるのです。
もしStringクラスの実装が変わり、内部のデータ構造が変化しても、上記のようなStringの機能を呼び出している側のコードに影響はありません。
これは、Java言語においておそらく最も身近な参照型であるStringクラスの例です。同様に、自分でも構造と振る舞いを持ったクラスを定義し、参照型として使用することができます。
これが、現在クラスベースのオブジェクト指向と呼ばれている考え方の基本になります。
クラスベースのオブジェクト指向についての説明だよ。
Javaはこれに該当するんですね。
次に、多態性についても解説しよう。
継承と多態性
クラスを用いて新しいデータ型を定義できるというクラスベースのオブジェクト指向の特性において、重要な要素が多態性(Polymorphism)です。
どのような場面で必要となるか、これもJava言語の学習でよく使用する、System.out.printlnを例に挙げて説明します。
Date date = new Date(); System.out.println(date); // 日付が表示される BigDecimal number = new BigDecimal(3.5); System.out.println(number); // 3.5という数字が表示される
printlnメソッドの引数に、一方ではDate型の変数を渡し、もう一方ではBigDecimal型の変数を渡しています。では、Date用のprintlnメソッドとBigDecimal用のprintlnメソッドがそれぞれ用意されているのでしょうか。
もちろん、そんなことはありません。新しい型はクラスを定義することでいくらでも増やすことができるため、一つ一つの型に対してメソッドを用意していくことは不可能です。
これを実現しているのが、継承と多態性です。DateもBigDecimalをはじめとして、すべてのJavaのクラスはObjectクラスを継承しており、Object型として振る舞うことができます。上記のコードは、以下のように解釈することができ、同じ実行結果となります。
Object date = new Date(); System.out.println(date); // 日付が表示される Object number = new BigDecimal(3.5); System.out.println(number); // 3.5という数字が表示される
Date型、BigDecimal型いずれの場合でも、Object型を引数にするprintlnメソッドが使用されます。このメソッドは、表示する文字列としてObjectクラスのtoStringメソッドの戻り値を使用します。
ここで、Dateクラス、BigDecimalクラスはそれぞれObjectクラスのtoStringメソッドを再定義(オーバーライド)しています。その結果、同じObject型としてtoStringメソッドを実行しても、Dateクラスのオブジェクトでは日付を示す文字列が、BigDecimalクラスのオブジェクトでは数値を示す文字列がそれぞれ返ります。
これによって無数のJavaクラスや、自分で新たに作成したクラスのオブジェクトを、printlnメソッドの引数として使用することができます。
もちろん、System.out.println以外でも様々なケースでこのような振る舞いは活用されます。データ型をクラスとして新しく定義できるという特性を活かすために、型を汎用的に操作するとともに、個々の振る舞いは定義されたクラス側によって変化するという性質は重要で、これが多態性の基本となります。
以上、オブジェクト指向について解説しました。
入門向けJavaの学習サイトもまとめているので、合わせてご覧ください。
継承と多態性について説明したよ。
メソッドの実行結果が、クラスによって変わるといった感じでしょうか。
オブジェクト指向について理解しておくことで、Javaの構成もより分かりやすくなると思うよ。改めて勉強してみよう。
そうですね、一度見直してみます。ありがとうございました!
TechAcademyでは、初心者でもJavaやServletの技術を使ってWebアプリケーション開発を習得できるオンラインブートキャンプを開催しています。
また、現役エンジニアから学べる無料体験も実施しているので、ぜひ参加してみてください。