Class is an object! - LOGOの後継SmallTalkはかく語りき
(タイトルは本文の内容を表してはいない。ちょっと言ってみたかっただけ)
Locの解説を「クラス」の解説無しでやってしまっているのを、今更ながら発見。
「書庫【Proce55ingで遊ぼ】を逆順で」とか言っているのに、解説の順序が逆になってしまった。
なので、Locの解説をこの後投稿し直すかも。(その場合,前記事は削除予定)
「書庫【Proce55ingで遊ぼ】を逆順で」とか言っているのに、解説の順序が逆になってしまった。
なので、Locの解説をこの後投稿し直すかも。(その場合,前記事は削除予定)
其の零 承前
Webで「クラス(+ Java)」を検索すれば、多種多様な解説が得られるので、あなたの好みのページで理解されるのが吉。ここでは、できるだけ直感的(と、いうことは不正確でぶっきらぼうな)解説を試みる。ここで理解した気になってくれた人が少しでもいてくれたらHappy。
ここまで、書庫(Proce55ingで遊ぼ)を逆順に読んでくれていたら、すでにぶつかっている疑問があると思う。
【変数】ってなに? 答えは、特定の【種類】の【値】を格納できる【コンテナ】。
【値】ってなに? 答えは、【種類】のなかのひとつ。一般に同じ【種類】の多くの【値】がある。
【種類】ってなに? 答えは、【変数】が格納できる【値】の総称。
【コンテナ】ってなに? 答えは、【変数】(合わせ鏡になっちゃった!)
【変数】ってなに? 答えは、特定の【種類】の【値】を格納できる【コンテナ】。
【値】ってなに? 答えは、【種類】のなかのひとつ。一般に同じ【種類】の多くの【値】がある。
【種類】ってなに? 答えは、【変数】が格納できる【値】の総称。
【コンテナ】ってなに? 答えは、【変数】(合わせ鏡になっちゃった!)
【変数】=【コンテナ】=「なにかしら格納できるもの」、ってすればとりあえず合わせ鏡にはならない。
其の壱 型
以前解説したなかに現れた【コンテナ】、【種類】、【値】の使用例は、int i=0;
・「int」は【種類】。数学で言う整数(Integer)のことを指す。(厳密にはちょっと違うけど気にしない)
例えば、右は整数の例 ・・・-1000,-32,0,99,・・・
・「i」は【コンテナ】。整数しか格納できない。(ということは、1.5は格納できない)
・「0」は【値】。ゼロは整数なので「i」は格納できる。
まとめると
【コンテナ】「i」は【種類】「整数」を格納でき,(今は)【値】「ゼロ」を格納している。
P5(=Java)であらかじめ使える【種類】は、「整数(int)」に加えて
「浮動小数(float)」 【値】は・・・-1000,-32.5,0,0.0000000000001,99,99.99999999999・・・
「文字列(string)」 【値】は"a","abc","あ","あいう","aあbcい","1","@1aう",・・・
:
*プログラミングの世界では、「あらかじめ使える【種類】」を「型」と呼ぶことが多い。
「浮動小数(float)」 【値】は・・・-1000,-32.5,0,0.0000000000001,99,99.99999999999・・・
「文字列(string)」 【値】は"a","abc","あ","あいう","aあbcい","1","@1aう",・・・
:
*プログラミングの世界では、「あらかじめ使える【種類】」を「型」と呼ぶことが多い。
また【コンテナ】は先頭が英文字ではじまる英数(一部記号)文字の列(単語)で好きなように名付けられる。
(「i」,「len」,「aL」、「l_12」は【コンテナ】の名前として使えるが、「3D」、「l 12」は【コンテナ】の名前には使えない)
(「i」,「len」,「aL」、「l_12」は【コンテナ】の名前として使えるが、「3D」、「l 12」は【コンテナ】の名前には使えない)
其の弐 配列
「配列(array)」も【種類】。(「一個以上の同じ種類の【コンテナ】でできている列」という【種類】のこと)ただし、書き方が上述の「型」とちょっと違う。int ia = new int[3];
・「int」は【種類】。「整数コンテナの配列」という種類(後述)。
・「ia」は【コンテナ】。「具体的な」コンテナの配列(=【値】、後述)を格納する。
・「int[3]」は【値】。「3個の整数コンテナが並んだ」具体的な配列。newで「あたらしく作れ」ってP5に伝える。
「配列」:一番目の要素はia[0]、二番目の要素ia[1]、・・・n番目の要素はia[n-1] と書ける。
だから、「整数の配列」の各々の要素は、「整数」の【コンテナ】として扱える。
前節の「型」と同じでしょ
例えば、
int[] ia = new int[3];
for (int i=0; i<3; i++) ia[i]=i+1;
とすると、ia[0]に1、ia[1]に2、ia[2]に3が格納された状態になる。for (int i=0; i<3; i++) ia[i]=i+1;
(new int[3];とやったらia[3]=1;とかやらないこと。
ia[3]は【4】番目の要素のことなので、P5から「どこにもないよ!」って怒られる)
其の参 クラス
クラスは【種類】、オブジェクトは【値】クラス、オブジェクトはなに?、ってのはとりあえず置いといて、
Loc pos = new Loc();
・「Loc」は【種類】。(「Loc」という【クラス】のこと)P5はLocという【クラス】を知らないので、別のところで定義しなくてはならない。(後述)
・「pos」は【コンテナ】。Locの【値】を格納する。
・「Loc()」は【値】。(Loc()が作るLocの【オブジェクト】のこと)newで「あたらしく作れ」ってP5に伝える。
前節の「配列」と同じでしょ
其の四 本題の【クラス】と【オブジェクト】
クラスは【種類】、オブジェクトは【値】(しつこい)P5の知らない【種類】を使うには、まずは下のようにして使いたいクラスをP5に教えてやることになる。
class Loc { //Locクラスという位置を表す【種類】とは、
float x,y,z; // float型の三つの【コンテナ】を持ち,
Loc() { x=y=z=0;} // Loc()で作られる場合は全部ゼロから始まる
Loc move(int xx, int yy, int zz) { // Locの【値】を返すmove【メソッド】とは、
x=xx;y=yy;z=zz; // 三つの【コンテナ】の【値】を言われた値にして
return this; // この【オブジェクト=値=自分自身】を返す。
}
}
上の記述は三次元空間の位置のモデル、Locクラスの基本的な定義。float x,y,z; // float型の三つの【コンテナ】を持ち,
Loc() { x=y=z=0;} // Loc()で作られる場合は全部ゼロから始まる
Loc move(int xx, int yy, int zz) { // Locの【値】を返すmove【メソッド】とは、
x=xx;y=yy;z=zz; // 三つの【コンテナ】の【値】を言われた値にして
return this; // この【オブジェクト=値=自分自身】を返す。
}
}
まず、【種類】を決めるクラスの名前(ここではLoc)をP5に教える。
*【コンテナ】の名前と区別しやいように先頭文字を大文字にしといた方が良い。
*【コンテナ】の名前と区別しやいように先頭文字を大文字にしといた方が良い。
つづいて、クラスを規定する実体(属性=メンバ=【コンテナ】)を並べる。
*ここでは、x,y,zの三つの浮動小数コンテナ
*実体は別のクラスの【コンテナ】でも、Locクラスの【コンテナ】でもOK
*pos.xでposが格納しているオブジェクトのメンバ「x」を【コンテナ】として扱える。
*前節の「配列」もメンバを持っている。ia.lengthで配列の長さ(要素数)を確認できる。
*ここでは、x,y,zの三つの浮動小数コンテナ
*実体は別のクラスの【コンテナ】でも、Locクラスの【コンテナ】でもOK
*pos.xでposが格納しているオブジェクトのメンバ「x」を【コンテナ】として扱える。
*前節の「配列」もメンバを持っている。ia.lengthで配列の長さ(要素数)を確認できる。
次に、オブジェクト(=クラスの【値】)の作り方(コンストラクタ)をP5に教える。
*実体(x,y,z)の最初の値(初期値)をセットすることが多い。
*上に加えてLoc(int all) {x=y=z=all;}のように別の作り方を並べても良い
*実体(x,y,z)の最初の値(初期値)をセットすることが多い。
*上に加えてLoc(int all) {x=y=z=all;}のように別の作り方を並べても良い
最後に、このクラスオブジェクトに対する操作とその内容(メソッド)をP5に教える。
*普通の関数と同じように記述するが、クラスの実体(メンバとメソッド)は自由に扱える。
*Locのmove()は位置を変えるメソッド。pos.move(1,1,1);でposは座標(1,1,1)になる。
*普通の関数と同じように記述するが、クラスの実体(メンバとメソッド)は自由に扱える。
*Locのmove()は位置を変えるメソッド。pos.move(1,1,1);でposは座標(1,1,1)になる。
で、(上の画像とはちょっと違う)例題。
Loc pos = new Loc(); // posに新しい【位置(0,0,0)】を格納。
void setup() {
rect(pos.x,pos.y,10,10); //posの【値=(0,0,0)】を左上とする10×10の正方形
pos.move(50,50,0); // posを座標(50,50,0)に移す。
rect(pos.x,pos.y,10,10); //posの【値=(50,50,0)】を左上とする10×10の正方形
}
*クラスの定義は別のタブに入れておいた方が整理がし易い。void setup() {
rect(pos.x,pos.y,10,10); //posの【値=(0,0,0)】を左上とする10×10の正方形
pos.move(50,50,0); // posを座標(50,50,0)に移す。
rect(pos.x,pos.y,10,10); //posの【値=(50,50,0)】を左上とする10×10の正方形
}
おまけ、クラスの継承
質点は位置を持った質量(高校物理?)じゃあ、質点のモデルをクラスで定義してみよう。
class Mass extends Loc { //クラスMassはLocの一種(extends)で、
float mass; // さらに質量を持つ。
Mass() {super();mass=1;} // 作成時に元クラス(super)の初期設定と質量の初期設定
float getWeight() { // 現在の「重量」を返すgetWeight【メソッド】とは、
return mass*9.80665; // おなじみ?質量と重力加速度の積(重量)を返す。
}
}
Massオブジェクトは質量を持ち地球上でのそのオブジェクトの重量を教えてくれるが、さらに位置(Loc)でもあるので、前の節の例題も難なくこなせる。float mass; // さらに質量を持つ。
Mass() {super();mass=1;} // 作成時に元クラス(super)の初期設定と質量の初期設定
float getWeight() { // 現在の「重量」を返すgetWeight【メソッド】とは、
return mass*9.80665; // おなじみ?質量と重力加速度の積(重量)を返す。
}
}
Mass mp = new Mass(); // 質点mpに新しい【位置(0,0,0)と質量(1)】を格納。
void setup() {
rect(mp.x,mp.y,10,10); //mpの【位置=(0,0,0)】を左上とする10×10の正方形
float weight = mp.getWeight(); //(何にも使わないけど)mpの重量を得る。
mp.move(50,50,0); // mpを座標(50,50,0)に移す。
rect(mp.x,mp.y,10,10); //mpの【位置=(50,50,0)】を左上とする10×10の正方形
}
void setup() {
rect(mp.x,mp.y,10,10); //mpの【位置=(0,0,0)】を左上とする10×10の正方形
float weight = mp.getWeight(); //(何にも使わないけど)mpの重量を得る。
mp.move(50,50,0); // mpを座標(50,50,0)に移す。
rect(mp.x,mp.y,10,10); //mpの【位置=(50,50,0)】を左上とする10×10の正方形
}
こんな便利なメカニズムを「継承」とよぶ。活用しない手はないっす!
山本徹(thoru)さんがFunProce55ingを始めてくれている。お絵描きを中心に非常にわかり易い、癒される解説
例題集は習作集と区別するために[http://www.geocities.jp/classiclll_newweb/tutrial.ht
例題集は習作集と区別するために[http://www.geocities.jp/classiclll_newweb/tutrial.ht