公開:2019.10.11 18:00:00 更新:2019.10.11 22:22:25 プログラミング総合

オブジェクト指向の簡単な説明 (クラスとインスタンス)

今回からはプログラミングの初心者の方のために、オブジェクト指向を「コンビニ」で説明します。
ただし範囲が広くなるので、今回は最も基本となる概念である「クラス」と「インスタンス」について解説していきます。

オブジェクト指向というものは「どう作るか」よりも「どう使うか」の方が大事なのでいきなり用例から入っていきます。

コンビニの例

まずコンビニを開店します。

Convini convini = new Convini();

次にコンビニに来店し、カートを手に取ります。

Cart cart = convini.getNewCart();

コンビニの商品を一覧で確認します。

convini.list("おにぎり");

上のメソッドの出力が以下のようになります (という設定です)。

商品番号 商品名         価格
1001     鮭おにぎり     122
1002     シーチキン     128
1003     おかか         124
...

カートに鮭おにぎりを2個と、シーチキンを1個入れます。

cart.add(1001);
cart.add(1001);
cart.add(1002);

カートを持ってレジに行き、会計を頼みます。

int price = convini.order(cart);

ここでpriceの値に122 + 122 + 128 = 372が設定されました。

次に支払いするため、財布からコインを取り出します。

Coin coins = mySaihu.getCoins(price);

取り出したコインをコンビニに支払います。

List<Onigiri> onigiri = convini.doRegister(coins);

doRegisterメソッドの戻り値が購入した商品になり、その中におにぎりが入っています。
これでおにぎりをゲットしました。

あとお釣りも受け取ります。実は先のmySaihu.getCoinsメソッドは手持ちの硬貨から近似値を返すのでお釣りが発生します。

mySaihu.addCoins(convini.getOtsuri());

こうすることでコンビニが返してくれたお釣りを財布に加えることになります。
以上が使い方なのですが、もう少し詳しく解説します。

クラスとインスタンス

クラスとは

まず上の例でConviniとかCartとかCoinとあるのは「クラス」というものの名前です。
「クラス」はオブジェクトが何を持つことができるか、何の仕事ができるかということを決めています。

インスタンスとは

conviniとかcartとかcoinsとあるものは「インスタンス」というものです。
インスタンスは何らかのクラスに属するオブジェクトです。

オブジェクトとは

プログラミングで言うオブジェクトとはやや曖昧な概念で一言で定義するのは難しいものです。
しかしだいたい以下のような意味で使われるので文脈に沿って解釈してください

  • メモリ上に展開されたデータのかたまり
  • インスタンスのこと
  • 操作の対象・目的物
補足

「ちょっとコンビニ行ってくる」という時、どの店に行くかというのは決めていなくても良いですよね?
そこに何があるか、何ができるか、というのが期待通りであれば良いのです。
そして街を歩いていてコンビニを見つけたら「このコンビニに入ろう」となるわけですよね。
つまり「どこかのコンビニ」というのが「クラス」を表しており、「このコンビニ」というのが「インスタンス」を表わしています。そしてどのコンビニも基本的に同じ商品を置いていて、同じ仕事をしています。おおざっぱに言えばですがね。
実際にはこのコンビニにしかない部分というのがあったりするんですが、それは次回に回します。
カートについても、商品を手で持ちきれない場合、どれでも良いからカートがひとつ欲しいとなります。そして実際に手に取るのはひとつの「このカート」となります。それは商品自体についても同じことが言えます。
それがクラスとインスタンスの関係となります。

コードについて

次にコードについて説明します。
コードは言語によってルールがありますが、基本的にC++やJavaの文法が広く知られています。

コンストラクタ

最初のコンビニ開店の例では下のような構文になっています。

 [クラス] [変数名] = new [クラス]([引数]);

=」の左側は変数宣言となっており、右側はコンストラクタとなっています。

変数宣言は「この変数を使いますよ」とコンパイラに伝えるものです。
その時点では変数は空で名前だけがあります。

変数とは値の入れ物に名前を付けたもののことです。
例えばポケモンで言えばピカチュウには「HP」とかがありますよね。
「HP」は変数でその値が130とか120とか変化するものです。

コンストラクタとはクラスのインスタンスを生成するものです。
=」によってコンストラクタで生成したインスタンスを変数に設定(代入)しています。
それによって変数をあるクラスのインスタンスとして使うことができるようになります。

メソッド

次にカートを取得するメソッドgetNewCartについてです。
このメソッドは新しい空のカートを一つ生成し、戻り値として返すメソッドです。
コンビニに「カート下さい」と頼めば持って来てくれるイメージとなります。
もちろん正確にはあらかじめ生成してあるカートを空にして渡してくれるわけですが。
構文としては以下のようになります。

 [クラス] [変数名] = [変数].[メソッド]([引数]);

これはConviniクラスのインスタンスconviniのメソッドgetNewCartを使うことによってカートを借りるということです。引数はありません。
クラスによってインスタンスが使えるメソッドが決まっています。
今回の例ではconviniが使えるメソッドは

  • getNewCart
  • list
  • order
  • doRegister

の4つです。
cartに使えるメソッドは

  • add

だけです。なのでcartorderメソッドは使えません。カートに入れた商品を元に戻すremoveメソッドがあってもいいかもしれませんね。
また、カートに入れた商品を確認するためのメソッドlistがあっても良いかも知れません。それは以下のようになるでしょう。

cart.list();

その出力は

商品番号 個数
1001     2
1002     1

conviniにもlistメソッドがありますが、同じ名前のメソッドでもインスタンスのクラスによって違うことをしていることが分かると思います。

またインスタンスは生成されたものごとに違う内容を持つことができます。
例えば2つのカートを借りて別の商品を入れるという場合です。

Cart cart1 = convini.getNewCart();
Cart cart2 = convini.getNewCart();

cart1.add(1001);
cart2.add(1003);

ここで、cart1.list()の出力は「1001 1」となり、cart2.list()の出力は「1003 1」となります。

終わりに

この例で使ったクラスは架空のものですが、オブジェクト指向がさまざまな種類のデータを処理するコードをシンプルに見せる仕組みであることは分かっていただけたでしょうか。

ところで「カートが仕事をするって変じゃないか?」と思った方もいるかもしれません。
それは、スポンジボブみたいなものだと私は考えています。アメリカのカートゥーンではモノがキャラ化することはよくありますよね。それに似ている気がしませんか?
でも結局は人の数だけオブジェクト指向の解釈があるようです。

次はオブジェクト指向プログラミングの非常に重要な3原則となる「継承」「カプセル化」「ポリモーフィズム」について説明したいと思います。