図1●お客から見た,キュウリを買いに行く作業のフロー
図2●店員から見た,お客にキュウリを売る作業のフロー
図3●店員オブジェクトの動作
図4●店長オブジェクト,奥さんオブジェクト,アルバイト・オブジェクトの仕事。簡単にするため,この八百屋の営業時間は考えていません。奥さんは深夜0時から午前中一杯がんばるようになっていますが,実質は午前中と理解してください
リスト1 ●あいさつするsayHello ,お礼を言うsayThankyou メソッドを 組み込んだ店員(clerk )クラスと,clerk クラスを継承した店長(chief ) クラス,奥さん(wife )クラス,アルバイト(parttimer )クラスのコー ド。店長,奥さん,アルバイトのオブジェクトは,特にメンバーに何も書 かなくても,二つのメソッドを実行できる
 本誌の読者の皆さんなら,「オブジェクト指向プログラミング」という言葉について,詳しい内容までは知らなくても,目にしたり,聞いたりしたことはあると思います。ひょっとしたら,“難しいもの”とか,“上級プログラマが学習するもの”と考えている人も多いかもしれません。

 しかしそれはまったくの誤解です。オブジェクト指向プログラミング自体はとてもシンプルで,プログラミングについて詳しくなくても理解できる考え方です。

 オブジェクト指向の考え方そのものは古くからあります。ただ,一般的なプログラミング言語で広く利用されるようになったのは比較的最近のことです。C++,Java,そして本連載の主役であるC#がその代表例でしょう。最近では,もともとオブジェクト指向言語ではなかったCOBOLやBASICなどでも,オブジェクト指向に対応した拡張版が登場してきています。

 もしオブジェクト指向プログラミングが本当に難しく,学習困難なものならば,わざわざ多くの言語が採り入れることはないでしょう。つまり,それだけ便利で有用だからこそオブジェクト指向プログラミングは普及してきているのです。そこで今回は,C#を学ぶうえで欠かせない,オブジェクト指向プログラミングについて,できるだけわかりやすく説明します。

八百屋にキュウリを買いにいく

 まずは,プログラミングとは離れて,オブジェクト指向の考え方をイメージとして理解することからスタートしましょう。オブジェクト指向プログラミングについての知識が多少あっても,今しばらく,コードに置き換えないで考えてみてください。

 さてあなたは,キュウリを3本買いに行くとします。持っているお金は100円だけ。近所には八百屋さんがあります。何をすればよいでしょうか。

 こんな問題は簡単ですね。八百屋に行って店員を呼んで,キュウリの値段を調べて,100円以内なら買ってくればいいのです。話がややこしくなるので,もっと安い店を探しに行くとか値切るとか,そういうことは除外します(図1[拡大表示])。

 今度は,八百屋さん側からこの様子を見てみましょう。八百屋の店員は,お客が来たら「いらっしゃい」と声をかけます。キュウリの値段を聞かれたら,適切な値段を答えます。お客が商品を買おうとしたら,商品とお金を交換して「ありがとうございました」と言います(図2[拡大表示])。買い物のシミュレーションはこんな具合になるでしょう。それではこれをオブジェクト指向的に見るとどうなるでしょうか。

オブジェクト「思考」してみる

 オブジェクト指向の考え方は,現実の世界での考え方に似ています*1。オブジェクト指向では,あらゆるものを「オブジェクト」としてとらえます。例に登場した“あなた”も“店員”も,場合によっては“八百屋”も,すべてオブジェクトになります*2。登場するもの,考えるべきものを「オブジェクト」としてとらえることがオブジェクト指向の基本です。

 オブジェクト指向的に考えると先の例は,“あなた”というオブジェクトが,“店員”というオブジェクトに対して「ごめんください」とか,「キュウリはいくらですか」とか,話しかけていることになります。それに対して,店員オブジェクトが適切な反応をしているわけです。では,店員オブジェクトの反応を考えてみましょう(図3[拡大表示])。

(1)「ごめんください」と呼ばれたら,「いらっしゃい」と答える
(2)キュウリの値段を聞かれたら,適切な価格を答える
(3)お客が買ったら「ありがとうございました」と答える

 本当は商品とお金のやり取りなども重要なのでしょうが,ここでは会話の部分だけを取り上げます。

 このようなオブジェクトの動作のことを「メソッド」といいます。つまり店員オブジェクトには,あいさつする「sayHelloメソッド」,キュウリの値段を答える「getPriceメソッド」,お礼を言う「sayThankyouメソッド」の三つがあるというわけです*3

 ここまで読んで敏感な方なら,キュウリの値段が決まっていないことに気がつかれたでしょう。実はこの八百屋さんでは店員として,店長,店長の奥さん,アルバイトの3人が交代制で働いています。午前中は店長の奥さんが働いています。正午から夕方の4時まではアルバイトが,4時以降は店長が店番をします。

 しかもそれぞれの店員で,キュウリの値段の付け方が違うのです。奥さんは少しでも高く売りたくて,標準価格の1割増で売ろうとします。アルバイトは,店で決められた通りの標準価格を答えます。店長は,少しでも多くのキュウリを売りたいので1割引きでサービスします。3人はみんな店員なので,あいさつやお礼は共通ですが,キュウリの値段については違うのです(図4[拡大表示])。

オブジェクトの動作と情報はクラスで定義する

 ここまでは,店員オブジェクトの実際の動作を説明してきました。では店員オブジェクトを作ることを考えてみましょう。オブジェクトを設計するには「クラス」というものを使います。クラスはオブジェクトの設計書と考えてください。

 例えば店員オブジェクトの動作は店員クラスで定義します。「メソッド(動作)」はクラスの中で決めるのです。また,クラスではメソッドだけでなく,「フィールド(情報)」も定義できます。店員クラスであれば,名前,勤続年数,時給といった,店員が持っているような情報がフィールドになります。

 フィールドとメソッドをまとめたものを「メンバー」といいます。さらに,フィールドの値の一部分を,取り出したり設定したりできるようにしたものを「属性(プロパティ)」といいます*4

 店員クラスで,店員というものがどのような動作をするのか,どのような特性をもっているのかを定義します。クラスはあくまで設計書に過ぎません。実際に利用するのはオブジェクトの方です。逆に言えば,店員クラス(という設計書)によって作られたものが店員オブジェクトということになります。

店員クラスをコーディングしてみる

 いろいろな言葉が一気に出てきて混乱したかもしれません。いつまでも文章で説明していては理解が進まないでしょうから,そろそろC#でプログラムを作ってみます。

 C#では,classキーワードをクラス名の先頭に付けてクラスを作成します。例えば店員(clerk)クラスなら

class clerk
{
//ここに店員メンバーを書く
}

のように書きます。

 クラス名の次の{ }(中カッコ)で囲まれた店員メンバーの部分には,クラスの動作(メソッド)や情報(フィールド)を記述します。メソッドには,そのメソッドがどのような値を返すかを示すキーワードを付け,その後にメソッド名を,それに続く{ }の中に具体的な処理内容を記述します。値を返す必要がない場合には,キーワードはvoidとなります。

 例えば,店員があいさつするsayHelloメソッドは,特に何かの値を返すわけではありませんから,

public void sayHello()
{
Console.WriteLine("いらっしゃい");
}

と書けます。publicというのは,他のクラスからsayHelloメソッドを利用できるようにするためのキーワードで,Console.WriteLineはコンソール・アプリケーションの標準出力(ディスプレイなど)に文字列を出力する命令です*5

継承でクラスの性質を引き継がせる

 ここまでで,とりあえず「いらっしゃい」と答える店員(clerk)クラスができました。でも店員は実際には3人いるのでしたよね。となると,3人分のクラスを設計しなければならないのでしょうか。ご安心を。実はオブジェクト指向の考え方にある「継承」を使えば,店員クラスの持つ性質を,店長,奥さん,アルバイトの3人のクラスに,そのまま引き継がせることができるのです。

 C#では,継承を「:(コロン)」を使って表します。具体的に店長(chief)クラスを作るコードを書いてみましょう。chiefクラスもclerkクラス同様にclassキーワードを使います。クラス名chiefの後ろに「:(コロン)」を付けて,継承元になるclerkを記した結果が以下のコードです。

public class chief : clerk
{
}

 chiefクラスのメンバーは何も記述していませんが,これだけで先に作ったclerkクラスのsayHelloメソッドをそのまま受け継ぐことになります。

 奥さん(wife)クラスやアルバイト(parttimer)クラスも,店長(chief)クラスと同様にして店員(clerk)クラスを継承させて作成すれば,メンバーとして何も記述しなくともsayHelloメソッドを組み込んだことになります。

 店員の性質として共通しているものは,sayHelloメソッドだけでなく,お礼を言うsayThankyouメソッドもあります。これも,sayHelloメソッドと同様に,店員(clerk)クラスのメンバーとして作ります(リスト1[拡大表示])。つまり店員(clerk)クラスにメンバーを追加すれば,継承している店長(chief)やアルバイト(parttimer)クラスにも,自動的にそのメソッドが受け継がれるというわけです。