18:オブジェクト指向とクラス

◆PROCESSINGで始めるゲーム作りとコンピュータ

Desktop18:オブジェクト指向とクラス

今日の話題

 

22:クラスの基本

前回説明した配列は、同じ種類の変数をひとまとめにして、添字で扱えるようにしたものでした。それと似たようなものにクラスがあります。

クラスといっても教室ではありません(笑)。PROCESSINGはオブジェクト指向言語に分類されるプログラミング言語ですので、クラスが扱えるのです。

オブジェクト指向言語とは、簡単に言うと「いろいろな情報を物(オブジェクト、塊)として扱い、オブジェクト同士を連携させて処理を行うプログラミング言語」です。

・・・と言っただけでは良くわかりませんよね(汗)。

例えばRPGに登場するキャラクターを考えてみましょう。

キャラクターには名前がありますよね。名前の他にも性別や種族といった属性、ヒットポイント(HP)やマジックポット(MP)などのパラメータがあります。

ヴァーミリオン キャラクターメイク
(画像URL:SQUEARE ENIX LOAR of VERMILION ARENA 様)

名前や種族は普通は文字列です。HPやMPは整数(数値)でしょう。これらを単純に変数で管理すると

のようになります。

これでも良いのですが、名前、性別、種族、HP、MPといった各パラメータがバラバラな感じがしませんか?。

この例のようにパラメータが5つ程度なら、あまり気になりません。でもパラメータが30個や40個もあったらどうでしょう?。

ちょっとゴチャゴチャして、扱いにくくなりそうです(汗)。

1人のキャラクターが、これらのパラメータを全て持ち合わせているのですから、各変数をバラバラに管理するのではなくて、キャラクター単位(キャラクターという塊単位)にまとめて扱えるとスッキリしそうです。

そこで登場するのがオブジェクト指向であり、クラスなのです。

クラスは意味のある塊(この場合はキャラクター)単位に、関連する情報をひとまとめにして扱う事が可能です。例えばキャラクターのクラスは以下のように定義できます。

こうする事で、キャラクター( character )単位に、関連する情報(名前、種族など)をひとまとめにして、扱えるようになるわけです。

シンプルなクラス定義

ここで例示したクラスの定義は非常にシンプルなものですが、ぱっと見て名前や属性などのパラメータが、キャラクターに関連するものだという事がよくわかります。

クラスの基本
(画像URL:illust-AC 様:sworc さん)

クラスには、ここで紹介した以外にも様々な機能や使い道があります。

しかしまずは最もシンプルに、配列変数よりも柔軟に、関連する情報をひとまとめにして扱えるものだと覚えて頂ければOKです。

上記のように定義したクラスからは、以下のようにして変数を作成します。

character  player ;
と書かれた箇所に注目して下さい。ここで player という名前の変数を宣言していますが、player という変数の型は character になっています!。

character は、その直前に定義されているクラスの名前でした。

今までは変数を利用する際に、整数( int )や文字列( String )など、PROCESSINGが用意している型を使いました。ところがなんと、クラスは型のように利用できるのです。

次に書かれている
player  =  new  character( );
という部分で、player という変数の実体を確保しています。

new は配列変数の説明でも登場しましたよね。new に続けて書いた型の領域を確保する命令でした。ここでは character というクラスの領域(実体)を作成しています。

クラス確保

クラスの場合、実は () の箇所に引数を与えて領域を確保する事も可能なのですが、それについては必要に応じて説明をしていきますので、ここでは触れません。

クラスを型にして作成された変数(実体)を、インスタンスと呼びます。

上記例では player がインスタンスになります。この部分は、以下のように1行で記述する事も可能です。

それでは、クラスの中にある name や syuzoku といった変数は、どうやって使うのでしょうか?。

クラス定義の中にある name や syuzoku などの変数は、メンバー変数と呼ばれます。そして各メンバー変数には、インスタンス名 . メンバー変数名  としてアクセスできます。例えばplayer の HP を100 に設定するプログラムは、以下のようになります。

シンプルなクラス操作

どうでしょうか?。意外と簡単ですよね(笑)。

 

23:スーパークラスと継承

上記で、クラスとは「ある物(塊、オブジェクト)」に関連する情報をまとめたものだと説明しました。

ここではRPGに登場する「人間」と「エルフ」を例に、それぞれが持っている属性をクラスで管理する場合を考えてみましょう。

例えば人間には、名前や性別、HP、MPなどの属性の他に、人間特有の属性である「国籍」があるとします。人間は必ずどこかの国家に所属しているという前提です。

一方で、精霊であるエルフには国家という概念がありません。その代わり人間にはない「守護精霊」という属性を持ち、何かの精霊に守られているとします。

あるClassの例(画像URL:illust-AC 様:sworcさん)

この場合、1つの方法として以下の様にクラスを作成(定義)する事が考えられます。

これでも良いのですが、名前、性別、HP、MPは人間にもエルフにもある共通の属性です。なので両方のクラスに定義するのは、ちょっと無駄っぽいですよね。

こんな時にスーパークラスを使います。

例えばこの例では、以下のように考えます。

継承1(画像URL:illust-AC 様:sworcさん、HI-TIME 様)

つまり人間もエルフも、それぞれ細かな特徴は違っているけど、同じ「人型(ヒューマノイド)」の一種だと考えるのです。

人間もエルフも人型の一種なので、ヒューマノイドが持っている共通の特徴(名前や性別)を当然持っていると考えます。

この考え方は非常に理に叶っています。

例えばここで新しい種族のドワーフが登場したとしても、ドワーフがヒューマノイドである限り、名前や性別といった属性は必ずもっていると考える事ができるからです。

これをもう少しコンピュータライクに書くと以下の様になります。

継承2(画像URL:illust-AC 様:sworcさん)

人間やエルフといったクラスは、その上位にあるヒューマノイドクラスの特徴を受け継いでいる(継承している)わけです。

そしてそれぞれが、人間クラスにしかない特徴(国籍)や、エルフクラスにしかない特徴(守護精霊)も持っています。

この時、上位にあるヒューマノイドクラスの事を、人間クラスやエルフクラスのスーパークラスと呼びます。そして上位にあるスーパークラスの特徴を受け継ぐ事を継承すると呼びます。

具体的には以下のようにプログラミングします。

human クラスや elf クラスの横にある extends と書かれた部分に注目して下さい。

これは、その後ろに書かれたクラス(humanoid)を継承する事を示しています。これで humanクラスは humanoidクラスの特徴を受け継ぐことになるのです。

継承定義受け継いた特徴は、さも初めから humanクラスや elfクラスが持っていたかのように扱う事が可能です。

以下の例を見て下さい。

継承テスト結果
どうでしょうか?。

継承を上手に使うと、共通の特徴を持ちつつ個性的な特徴も合わせ持ったクラスが簡単に作成できるようになります。

RPGで言えば、ヒューマノイドというクラスを使えば、人間やエルフ以外にも、ドワーフやハーフリング、ノームのような様々な種族を効率よく生み出す事ができるのです。

これがオブジェクト指向言語の醍醐味です。ちょっとワクワクしませんか?(笑)。

 

24:プロパティとメソッド

クラスには、様々なメンバー変数を格納できます。先程の例なら、名前や性別などの変数がそれです。

クラスが管理している(クラスに含まれている)メンバー変数の事を、専門用語で「プロパティ」と呼びます。

その一方で、クラスにはプロパティ以外にも関数を格納する事ができます。

例えば戦士クラスがあったとして、そこには戦士のヒットポイントや腕力といった属性(プロパティ)以外に、戦士がもつ能力(攻撃する、逃げる、防御する、寝る(笑)・・・など)を定義することができるのです。

たとえば上記の 戦士クラス(Warriorクラス)には、攻撃機能(Attack関数)、防御機能(Defense関数)、寝る機能(Sleep関数)があります。

これが僧侶クラスなら、祈る機能(祈り関数)や寄付を募る機能(托鉢関数)があるかもしれません(笑)。

methodsample3(画像URL:illust-AC 様:sworc さん、ニコニコ静画 様:ちーくんさん)

なぜ、クラスに関数が定義できるのでしょうか?。

例えばRPGなどでは

  • 戦士は武器で攻撃ができるけど呪文は使えない
  • 魔法使いは武器で攻撃はできないけど呪文を唱えることができる

などの設定が良くありますよね。

攻撃する機能(Attack関数)や呪文を唱える機能(Spell関数)は、クラスとは無関係に作成する事も可能です。例えば下記のような感じです。

一見何の問題もないように思えます。ですが、このプログラムでは以下のような事ができてしまいます。

<出力サンプル>
methodsample1
プログラムミスといえばそれまでですが、このような事が簡単にできてしまっては、せっかくのゲーム設定が台無しです。

methodsample4(画像URL:画像URL:illust-AC 様:sworc さん、麦さん、Kamesan さん)

攻撃する機能は戦士だけのもの、呪文を唱える機能は魔法使いだけのものにすれば、このようなミスは起こりません。

そこで攻撃機能は戦士クラスに、呪文機能は魔法使いクラスに含めてしまいます。例えば以下のような感じです。

こうすると

<出力サンプル>
methodsample2
呪文は魔法使いだけが使える機能(関数)になります。戦士がうっかり呪文を唱えようとしても( fighter.Spell() )エラーとなるのです。

このようにクラスには属性(プロパティ)だけではなく、そのクラスが持っている特徴的な機能(関数)を含めるのが一般的です。

こうする事でミスを防止できますし、魔法使いだから呪文を唱えることができる(魔法使いクラスには、呪文を唱える機能がある)というのは、非常に理にかなっていてわかりやすいです。

専門用語では、クラスの中に格納された機能(関数)の事を「メンバー関数」とか「メソッド」と呼びます。

 

Forest今日の言葉

・オブジェクト指向言語

いろいろな情報を「物(意味のある塊)」として扱うプログラミング言語です。IT業界では流行の言語です。プロを目指す方は避けては通れないでしょう。でもちょっと遊びで使う分には、難しく考える必要はありません(笑)。

・クラス

意味のある塊(オブジェクト)単位に、関連する情報や処理をひとまとめにしたものです。RPGのキャラクターに関連する情報(名前、性別、HPなど)をまとめたものと思えば、理解しやすいでしょう。

・インスタンス

クラスを型にして作成された変数(実体)の事です。インスタンス変数とも言います。クラスが雛形なら、インスタンスは実体です。クラス=タコ焼きの鉄板なら、出来上がったタコ焼きはインスタンスです(笑)。

・メンバー変数

クラスの中に定義されている変数の事です。

・スーパークラス

オブジェクト指向言語の特徴の1つです。あるクラスの特徴を受け継いだ別のクラスを作成する時、元となったクラスの事をこう呼びます。日本人というグループ(仲間)の1人に私達がいるなら、私達から見て日本人という塊はスーパークラスになります。

・継承

オブジェクト指向言語の特徴の1つです。あるクラスの特徴を受け継ぐ事をこう呼びます。コウモリは鳥の仲間か動物の仲間かという童話がありましたが、Javaでは童話のコウモリさんのように複数のグループ(クラス)の特徴を受け継ぐことは出来ません。

・プロパティ

メンバー変数のことです。クラスに格納された変数の事をこう呼びます。

・メソッド

メンバー関数ともいいます。クラスがもつ機能のことです。

 

scroll今日の文法

・インスタンス名 . メンバー変数名

クラス内のメンバー変数にアクセスする方法です。

 

extends

クラスの継承を指定します。

上記でエルフクラスは、人型クラスの特徴を継承しています。

 今日のまとめ

  • クラスとは、関連する情報を塊としてまとめたもの
  • PROCESSINGにはBasicモードとContinuousモードがある
  • Continuousモードは関数とクラスを利用する
  • 元になるクラスをスーパークラスと呼び、受け継ぐことを継承と呼ぶ

19:PROCESSINGと関数 へ進む
17:定数と配列変数 へ戻る
目次へ戻る


本ページで利用している特に参照元記載のないアイコン画像は、下記サイト様より拝借しております。各画像の著作権は、それぞれのサイト様および作者にあります。