さて、前回の授業で何となくオブジェクト指向の概念は分かってもらえたと思います。
今回は、オブジェクトに柔軟性と拡張性を与えるための機能である「継承」を学びます。
継承は、簡単に言ってしまえば「遺伝」です。
親から子が産まれる時に親のDNAを引き継ぎますが、完全に親のコピーなわけではありません。当然成長による新たな能力の獲得があります。
このように、クラスが型だとすると、その型の属性を引き継ぎなおかつ新しい属性を付加したクラスを作成することを「継承」と呼ぶのです。
では、実際にやってみましょう。
まずは、前回の授業で作ったCircleクラスを使います。コードが長くなってくると非常に読みづらいので、それぞれのクラスはファイルごとに分けましょう。
画面右上のボタンからNew Tabをクリックします。
更に、この新しいタブの名前をクラス名であるCircleにします。
この新しいCircleクラスのファイルに、クラスの定義の部分だけコピーし、目的のフォルダ内に保存します。この場合、
例えば、Circleクラスをファイルにする場合には、ファイル名は必ずクラス名と同じでなければいけません。一度クラスファイルを作ったら、それ以降はSketchメニュー > Add File…で他のプログラムにコピーすることができます。
例えば、circleSampleというフォルダの中でCircleクラスファイルを使う場合は以下のようなディレクトリになります。
circleSampleファイルをもう一度開くと、Processing上では以下のようにCircleファイルが追加されます。
フォルダ内のクラスファイルは全てProcessingのインタフェース上に表示されます。
クラスの継承の前に、複数のクラスを合成したクラスを作ってみましょう。以下のようなグラフィックになります。

先ほど作ったCircleクラスファイルと、新たにRectクラスを作ります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | class Rect{ float xPos, yPos; //x座標、y座標 float angle; //正方形の回転角度 int rSize; //正方形のサイズ float speed; //移動スピード Rect(float y, int rs, float sp){ //コンストラクタ rectMode(CENTER); //基準点を正方形の中心にする xPos = 0.0; yPos = y; angle = 0.0; rSize = rs; speed = sp; } void update(){ noFill(); xPos += speed; //speed分のx座標を移動 if (xPos > width) { //円のx座標がウィンドウの幅を超えたら、 xPos = 0; //位置を0に戻す } pushMatrix(); //座標を保存 translate(xPos, yPos); //基準点を移動 rotate(angle); //回転 rect(0, 0, rSize, rSize); //正方形を描画 popMatrix(); //座標を復帰 angle += 0.01; } } |
さらに、CircleクラスとRectクラスを合成した、CircleRectクラスを作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | class CircleRect{ Circle myCircle; Rect myRect; CircleRect(float y, int eSize, int rSize, float sp){ myCircle = new Circle(y, eSize, sp); myRect = new Rect(y, rSize, sp); } void display(){ myCircle.update(); myRect.update(); } } |
CircleRectクラスの中でCircleクラスとRectクラスのインスタンスを作成している訳です。
これを最終的に、circleRectSampleファイル内で呼び出します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | CircleRect cr1, cr2; //Circleクラスのオブジェクト(インスタンス)を宣言 void setup() { size(200, 200); smooth(); stroke(0); //引数はCircleRect(y座標, ellipseのサイズ、rectのサイズ、スピード)となる cr1 = new CircleRect(50, 5, 20, 0.1); //オブジェクトを作成 cr2 = new CircleRect(120, 40, 60, 0.3); //オブジェクトを作成 } void draw() { background(255); //背景は白 cr1.display(); //c1, c2オブジェクトのupdateメソッドを実行 cr2.display(); } |
最終的には以下のようなファイルの構成になります。
さて、ここからが本番のクラスの継承です。Circleクラスはそのまま使いますが、このクラスを継承して色彩の機能を持たせたColorCircleクラスを作成します。最終的には別々の色彩を持った円を作成します。

1 2 3 4 5 6 7 8 9 10 11 12 | class ColorCircle extends Circle { //Circleクラスを継承したColorCircleクラス color eColor; //色彩の変数であるeColorを宣言 ColorCircle (float y, int es, float sp, color c) { //初期化用のメソッド(コンストラクタ) super(y, es, sp); //親のクラスであるCircleクラスのコンストラクタを実行する eColor = c; } void createColor(){ fill(eColor); //色彩を設定 } } |
このクラスを宣言することによって、円に色を定義することが可能になりました。
この場合のCircleクラスを親クラス、もしくはスーパークラス、ColorCircleクラスを子クラス、もしくはサブクラスと呼びます。親子の関係となっているということですね。
そして、最終的にcolorCircleSampleファイルでColorCircleクラスのインスタンスを使います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ColorCircle c1, c2; //ColorCircleクラスのオブジェクト(インスタンス)を宣言 void setup() { size(200, 200); smooth(); //図形の輪郭をきれいに描画 noStroke(); fill(0); //黒で描画 c1 = new ColorCircle(40, 10, 1.0, color(255, 0, 0)); //オブジェクトを作成 c2 = new ColorCircle(150, 40, 3.5, color(0, 0, 255)); } void draw() { background(255); //背景は白 //c1オブジェクトのクラスであるColorCircleクラスのcreateColorメソッドを実行 c1.createColor(); //c1オブジェクトの親クラスであるCircleクラスのupdateメソッドを実行 c1.update(); c2.createColor(); c2.update(); } |
Sorry, comments are closed.