この記事はプログラムの構造をProcessingを通じて理解していくための記事です。
今回はクラスについて書いていきます。
目次
0.クラスとは
1.あらかじめ用意されているクラス
2.自分で定義してつくるクラス
0.クラスとは
0-0. クラスとは
関連するフィールド(変数)とメソッド(関数)が入ったテンプレート(型)のことです。
よくレシピや設計図などに例えられます。
0-1. なぜクラスを使うのか
主な理由は、
①プログラムが読みやすくなるから。
②再利用できるようになるから。
(再利用については後ほど詳しく)
0-2. クラスの種類
クラスには、"あらかじめ用意されているクラス"と、"自分で定義してつくるクラス"があります。
あらかじめ用意されているクラスは、具体的には、String,PImage,PFont,PShape,PVector...などです。
1.あらかじめ用意されているクラス
Processingでは、たくさんのクラスがあらかじめ用意されています。
String,PImage,PFont,PShape,PVector...など。
1-0. あらかじめ用意されているクラスの使い方
クラスはただのテンプレート(型)なので、そのままでは使うことができません。
なので、
①クラスを具体化してオブジェクトをつくる
②オブジェクトに中身を入れる
③オブジェクトを変数として扱う
という手順で、クラス(のなかの情報)を使っていきます。
簡単な例で見てみましょう。
//オブジェクトの宣言
String s1;
//オブジェクトの定義
s1 = "breakfast"
//オブジェクトの使用
println(s1.length());
9
このプログラムは、文字の長さを取得して表示するプログラムです。
手順ごとに詳しくみてみます。
①クラスを具体化してオブジェクトをつくる
//オブジェクトの宣言
String s1;
②オブジェクトに中身を入れる。
//オブジェクトの定義
s1 = "breakfast"
③オブジェクトを変数として扱う
//オブジェクトの使用
println(s1.length());
全てのオブジェクトはクラスが持つフィールドとメソッドを持っています。
オブジェクトの持つフィールドやメソッドにアクセスするためにはドット(.)を使ってアクセスします。
オブジェクト自体は、変数と同じように扱います。
変数と同じように使うとは
定義(宣言→初期設定)→使用
のようにして使うということです。
2.自分で定義してつくるクラス
プログラミングでは自分のオリジナルのクラスを作ってプログラムをシンプルにすることができます。
最初は、以下の跳ねるボールを表示するプログラムを簡略化していきます。
//使う変数の準備
float x = 30;
float y = 30;
float xspeed = 5;
float yspeed = 3;
//初期設定
void setup(){
  size(398,198);
}
//無限ループ
void draw(){
  //背景を毎フレーム描く
  background(255);
  //円の描写
  noStroke();
  fill(234,159,217);
  ellipse(x,y,50,50);
  
  //円の動き
  x += xspeed;
  y += yspeed;
  
  //画面端に着いたら跳ね返る
  if(x > width-20 || x < 20){
    xspeed *= -1;
  }
  //画面端に着いたら跳ね返る
  if(y > height-20 || y < 20){
    yspeed *= -1;
  }
}
プログラムを簡略化するために、
①モジュール化する
②再利用可能にする
ということをしていきます。
2-0.モジュール化する
float x = 30;
float y = 30;
float xspeed = 5;
float yspeed = 3;
void setup(){
  size(398,198);
}
void draw(){
  background(255);
  
  //モジュール化した関数を使う
  display();
  move();
  edges();
}
//ボールを表示する関数
void display(){
  fill(234,159,217);
  noStroke();
  ellipse(x,y,30,30);
}
//ボールを動かす関数
void move(){
  x += xspeed;
  y += yspeed;
}
//ボールを跳ね返らせる関数
void edges(){
  if(x > width-15 || x < 15){
    xspeed *= -1;
  }
  if(y > height-15 || y < 15){
    yspeed *= -1;
  }
}
Point :
まとめて1つの関数とすることで、draw()関数の中がすっきりしてプログラムがわかりやすいものになります。
2-1.再利用可能にする
再利用が可能とは、複数の出力が可能ということです。
//オブジェクトの宣言
Ball b1;
Ball b2;
void setup(){
  size(600,400);
  //オブジェクトを定義する
  b1 = new Ball(50,50,7,5);
  b2 = new Ball(400,50,-7,-5);
}
void draw(){
  background(255);
  //オブジェクトb1をつかう
  b1.display();
  b1.move();
  b1.edges();
  
  //オブジェクトb2をつかう
  b2.display();
  b2.move();
  b2.edges();
}
//クラスを定義する
class Ball{
  //使う変数(フィールド)を宣言する
  int x;
  int y;
  float xspeed;
  float yspeed;
  
  //Ballクラスのコンストラクタ
  Ball(int xpos,int ypos,float xvelocity,float yvelocity){
    x = xpos;
    y = ypos;
    xspeed = xvelocity;
    yspeed = yvelocity;
  }
  
  //ボールを表示する関数(メソッド)
  void display(){
    fill(234,159,217);
    noStroke();
    ellipse(x,y,30,30);
  }
  
  //ボールを動かす関数(メソッド)
  void move(){
    x += xspeed;
    y += yspeed;
  }
  
  //ボールを跳ね返らせる関数(メソッド)
  void edges(){
    if(x > width-15 || x < 15){
      xspeed *= -1;
    }
    if(y > height-15 || y < 15){
      yspeed *= -1;
    }
  }
}
2-2.再利用可能にする手順
①クラスの枠組みをつくる
class Ball{
}
②モジュール化した関数を入れる
(構造がわかりやすいように中身は抜いています。)
class Ball{
  //ボールを表示する関数(メソッド)
  void display(){
  }
  //ボールを動かす関数(メソッド)
  void move(){
  }
  //ボールを跳ね返らせる関数(メソッド)
  void edges(){
  }
}
③関数(メソッド)に使う変数(フィールド)を準備する。
//クラスを定義する
class Ball{
  //使う変数(フィールド)を宣言する
  int x;
  int y;
  float xspeed;
  float yspeed;
  //ボールを表示する関数(メソッド)
  void display(){
  }
  //ボールを動かす関数(メソッド)
  void move(){
  }
  //ボールを跳ね返らせる関数(メソッド)
  void edges(){
  }
}
④オブジェクトを宣言する。
//使うオブジェクトb1を宣言する。
Ball b1;
//使うオブジェクトb2を宣言する。
Ball b2;
void setup(){
}
void draw(){
}
class Ball{
}
⑤オブジェクトに中身を入れる
オブジェクトの宣言
Ball b1;
Ball b2;
void setup(){
  //オブジェクトb1にBallクラスのインスタンスを代入する。
  //インスタンスはクラスを具体化したもの。
  //オブジェクトb1,b2は変数として扱われる。
  b1 = new Ball();
  b2 = new Ball();
}
void draw(){
}
class Ball{
}
Point :b1⬅︎new Ball()
BallクラスのインスタンスBall()をオブジェクトb1に代入しています。
⑥オブジェクトを使う。
※全てのオブジェクトは、クラスの持つフィールド(変数)とメソッド(関数)を持っています。
自身の持つフィールドやメソッドにアクセスする場合は、ドット(.)を使います。
Ball b1;
Ball b2;
void setup(){
  b1 = new Ball();
  b2 = new Ball();
}
void draw(){
  //ドット(.)を使って、オブジェクトの中のメソッドにアクセスする。
  b1.display();
  b1.move();
  b1.edges();
  //ドット(.)を使って、オブジェクトの中のメソッドにアクセスする。
  b2.display();
  b2.move();
  b2.edges();
}
class Ball{
}
⑦クラスのコンストラクタをつくる
コンストラクタは、クラスから複数のオブジェクトを生み出すために必要なものです。
オブジェクトが、クラスの中の関数にアクセスするためのものです。
//オブジェクトの宣言
//まだ中身は何も入っていない
Ball b1;
Ball b2;
void setup(){
  //オブジェクトの生成(定義)
  //クラスを具体化したインスタンスを、つくったオブジェクトに代入する
  //オブジェクトに個性を持たせるようなイメージ
  b1 = new Ball(50,50,7,5);
  b2 = new Ball(400,50,-7,-5);
}
void draw(){
  //ドット(.)を使って、オブジェクトの中のメソッドにアクセスする。
  b1.display();
  b1.move();
  b1.edges();
  //ドット(.)を使って、オブジェクトの中のメソッドにアクセスする。
  b2.display();
  b2.move();
  b2.edges();
}
class Ball{
  //使う変数(フィールド)を宣言する
  int x;
  int y;
  float xspeed;
  float yspeed;
  //Ballクラスのコンストラクタ
  //データ型 変数 という形で変数を宣言する
  //これによってオブジェクトを個性的にすることができる
  Ball(int xpos,int ypos,float xvelocity,float yvelocity){
    x = xpos;
    y = ypos;
    xspeed = xvelocity;
    yspeed = yvelocity;
  }
  void display(){}
  void move(){}
  void edges(){}
}
Point :コンストラクタ
コンストラクタは、インスタンスとフィールドをつなげるものです。
これによって、オブジェクトに個性をつけることができます。
逆にいうと、違いをつけたい部分を、コンストラクタで設定します。
(今回の場合)
7 = float xvelocity = float xspeed
プログラムが実行されたとき、xspeedには7が代入されます。
Point :インスタンス
オブジェクトが具体化したもの。
今回でいうと、**Ball(50,50,7,5)**がクラスのインスタンスの1つ。
Ball(400,50,-7,-5)もクラスのインスタンスの1つ。
同じクラスからインスタンスは複数つくることができる。
最後に
読んでいただきありがとうございました。
より良い記事にしていくために御意見、ご指摘のほどよろしくお願いいたします。
※この記事は、ダニエルシェフマン氏のyoutube"Coding Train"を参考にしています。
