いまさら聞けないJavaによるオブジェクト指向の常識:プログラマーの常識をJavaで身につける(11)(4/5 ページ)
本連載は、Java言語やその文法は一通り理解しているが、「プログラマー」としては初心者、という方を対象とします。Javaコアパッケージを掘り下げることにより「プログラマーの常識」を身に付けられるように話を進めていきます。今回は、Javaを学習する際によく耳にする「オブジェクト指向」について。いまさら聞けない人はぜひ読んでみてください。
「メッセージ・パッシング」、Javaではメソッド呼び出し
ラーメン屋では、「ラーメン屋のお客」が「ラーメン料理人」にラーメンを注文することにより、「ラーメン」を受け取ります。これをオブジェクト指向に当てはめて考えると、複数のオブジェクトが協調して動作することにより、目的を果たしているといえます。
複数のオブジェクトが協調して動作するには、オブジェクトからオブジェクトに「何か」を伝えなくてはなりません。この、オブジェクトに伝える「何か」をメッセージ、オブジェクトにメッセージを伝えることを「メッセージ・パッシング」と呼びます。
ラーメン屋の例でいうと、「ラーメン屋のお客」から「ラーメン料理人」にラーメンを注文することが、まさにメッセージ・パッシングの1つに相当します。前述のプログラムでは、以下のように表現されています。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
Java言語上では、メッセージ・パッシングはメソッドの呼び出しとして表現されます。このとき、メッセージを送るオブジェクトが、メッセージを受け取るオブジェクトのメソッドを呼び出している点に注意してください。
コラム 「同じ言葉でも意味が違う“インターフェイス”」
オブジェクト指向の基本概念を説明する際に、あるオブジェクトが受け取ることができるメッセージをまとめて「インターフェイス」と呼ぶことがあります。この「インターフェイス」は、Java言語仕様上の「インターフェイス」とは意味が異なる点に注意してください。
「カプセル化」、Javaではアクセス修飾子などで実現
ここで、ラーメン屋のお客が勝手に、ラーメンのスープを「ぜんざい」に変えようと試みます。
ところが、RamenオブジェクトのfSoupフィールドの値を「ぜんざい」に変えようとしても、コンパイルエラーが発生して変更できません。これは、fSoupフィールドがprivateでアクセス修飾されているからです。また、fSoupフィールドを変更するためのメソッドも提供されていないため、ラーメンのスープを勝手に変えることはできません。
また、そもそもfSoupがprivateでアクセス修飾されているので、外部からはスープがfSoupとして表現されていることを知る必要もありません。getSoupメソッドを使ってスープを取得する限り、ラーメン・クラスの内部でスープの表現方法が変わっても影響を受けません。
このように、公開されている(オブジェクト指向でいう)インターフェイスを通してオブジェクトにアクセスすることにより、オブジェクトのデータが誤って変更されることを防いだり、データの内部表現の変更による影響を無視できるような性質を、「カプセル化」と呼びます。
Java言語では、アクセス修飾子(public、protected、private)やパッケージなどを用いてカプセル化を実現しています。
「多態性」、同一のメッセージで異なる振る舞い
いままで登場した「ラーメン」「チャーシューメン」「ねぎラーメン」には、ラーメンを表示するという目的の類似したメソッドがあります。ここでは、IRamenインターフェイスを導出して、ラーメンを表示するという共通したメソッドを持たせることにします。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
「ラーメン・クラス」を以下のように書き変えます。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
同じように、チャーシューメン・クラス(CharSiuRamen)とねぎラーメン・クラス(LeekRamen)の「ラーメンを表示」メソッドのメソッド名も変更します。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
IRamenインターフェイスを導入したことにより、ラーメン屋のお客は、ラーメンの種類にかかわらず、IRamenインターフェイスを通じてラーメンのインスタンスを扱うことができるようになります。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
この変更によって、ラーメンの種類ごとにラーメンの表示メソッド名を変更する必要がなくなりました。注文メソッドをacceptLeekRamenOrderに変えてみて、コンパイルおよび実行ができることを確認してみましょう。
このように、異なる種類のクラスからなるオブジェクトが、同一のメッセージを受け取れることを保証しながら、そのメッセージに対してオブジェクトごとに異なる振る舞いができる性質を、「多態性」と呼びます。
instanceof演算子を使うと、どのクラスか分かる!
一方で、いま扱っているインスタンスが、どのクラスのインスタンスであるのかを調べる必要が出てくることがあります。このような場合には、instanceof演算子を利用して、どのクラスのインスタンスであるかを調べることができます。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
最後の次ページでは、Java APIの「裏技」について解説し、難しいオブジェクト指向を習得するためのヒントを教えます。
Copyright © ITmedia, Inc. All Rights Reserved.