6.オブジェクトに新しい能力を付け加えよう!(メソッドの定義)

 前回はタイマーオブジェクトを使って、複数の時間の流れを作って、違った時間の中でオブジェクトを動かしてみました。
 ここではオブジェクトに命令(メソッド)を追加し、さらに複雑なことをすることに挑戦します。
 この章ではオブジェクトに新しい能力を付け加えてみます。

 6-1.変数の利用。


 新しい命令を付け加える前に変数について説明をします。
 次のように変数Xを定義して、それを使って、正方形と円をかかせてみましょう。
*ドリトルではアルファベットの変数は大文字、小文字、全角、半角を区別しません。つまり、(全角)X、x、(半角)X,xは全て同じ変数となります。

//タートルオブジェクトの生成
かめ太=タートル ! 作る。

//変数に数値を代入
X=50。

//変数を使って、図をかかせる。
「かめ太! (X) 歩く 90度右回り」! 4回 繰り返す。
かめ太! (X) えん。
かめ太! (X*2) えん。

*1辺50の正方形、直径50、直径100の円をかきました。

 「X=50。」を変更することで図の大きさを簡単に変えることができます。変数Xに代入する値をいろいろと変えて試してみてください。

<数式>
かめ太! (X*2) えん。

 数式は(x*2)と( )で囲みます。変数を使う時は変数も数式と見なして、( )で囲みます。
 ドリトルでは後置記法(逆ポーランド記法)といって、「○○ 歩く」や「1!2 たす。」というように日本語の語順と同じように後から何をするかを指定する形で記述をしますが、( )で囲んだ中だけは別世界です。

 x=1!2 たす。 //1に2を足す。
 x=(1+2)。   //1たす2

 数学の時間ではこの2つを無意識のうちに使い分けていると思います。
 ドリトルでも同じように()内は別世界と頭を切り換えてください。
 数式にはどんな演算子が使えるかはマニュアルを見てください。


<ブロックオブジェクト>
一連の動作を「 」で囲むと「 」で囲まれたものを一つのオブジェクトとして扱えます。

「かめ太! (X) 歩く。 90度右回り」! 4回 繰り返す。

 は「かめ太! (X) 歩く。 90度右回り」をオブジェクトとし、それに4回繰り返すように命令していることになります。



 6-2.オブジェクトに命令を付け加える。



さて、いよいよオブジェクトに命令(メソッド)を追加してみましょう。
次のサンプルプログラムを入力してみてください。「かめ太:走る」と「:」を使って、かめ太が「走る」を実行できるように定義しています。

//タートルオブジェクトの生成
かめ太=タートル ! 作る。

//かめ太に「走る」能力を追加
かめ太:歩幅=2。
かめ太:走る=「|x|かめ太! (X*歩幅) 歩く」。
かめ太! 50 走る。

*100歩 歩く距離と同じだけ進みます。

 これで、これまで歩くことしかできなかった「かめ太」が走ることができるようになりました。つまり、「かめ太」に「走る能力」が備わったわけです。

 かめ太には「歩幅」と「走る」という属性が定義されました。
 かめ太の歩幅は2で、50走ると100歩歩いたのと同じだけ進むということになります。

 このようにオブジェクトの属性にブロックを格納すると命令として使えるようになります。
 一連の動作をブロックオブジェクトとして、属性に格納していけば、複雑な動作を一言で命令できるようになります。

 あなたの手でオブジェクトを育てていくことができるわけです。

<引数>
かめ太:走る=「|x| かめ太! (X*歩幅) 歩く」。

ここで|x|と||で囲まれているところで引数宣言をしています。「○○ 走る」と実行時点でどれだけ走るかを指定できるように○○という数値を受け取ってxに格納しています。引数は「」内(ブロック内)で有効です。


<変数の範囲>
 ここまで3種類の変数が出てきました。それぞれの変数の範囲を説明します。

●グローバル変数
 (例) x=3。
  プログラム全体で使える変数。
  x=3と定義すると、プログラム内では変更しないかぎりxは3である。

●オブジェクトの変数
 (例)かめ太:歩幅x=3。
   かめ太にのみ有効な変数。

●メソッドのローカル変数
 (例)
かめ太:走る=「|x| かめ太! (x*歩幅) 歩く」。

 |x|は「 」内でのみ有効な変数で、「かめ太! ○○ 走る。」と命令された時に○○という数値を受け取り「」内で使える変数となります。



 
6-3.オブジェクトのコピー


 さて、もう一つ、オブジェクトを作って、それにも「走る」という能力を身につけさせましょう。
 次のサンプルプログラムを実行してみてください。

//タートルオブジェクトの生成
かめ太=タートル ! 作る。
かめ子=タートル ! 作る
かめ子! "ayumiAka.gif" 変身する。

//かめ太に「走る」能力を追加
かめ太:歩幅=2。
かめ太:走る=「|x|かめ太! (X*歩幅) 歩く」。
かめ太! 50 走る。
かめ子! 100 走る。


*かめ子は「走る」能力を持っていないので、エラーとなって、動けません。(かめ太とかめ子の様子を見るためにエラーメッセージを少し上に移動して、確認した図)


 かめ子にも「走る」能力を身につけさせるには「かめ太」と同じように定義をしてやればいいのですが、結構、面倒です。
 それを簡単にやるためには「かめ子=タートル! 作る。」を「かめ子=かめ太! 作る。」としてみてください。
 かめ太に自分のコピーを作らせ、それをかめ子としています。これによって、かめ太の能力はかめ子にコピー(継承)され、かめ子でも「走る」が使えるようになります。


//タートルオブジェクトの生成
かめ太=タートル ! 作る。
かめ子=かめ太 ! 作る
かめ子! "ayumiAka.gif" 変身する。

//かめ太に「走る」能力を追加
かめ太:歩幅=2。
かめ太:走る=「|x|かめ太! (X*歩幅) 歩く」。
かめ太! 50 走る。
かめ子! 100 走る。


*かめ子は「走る」能力をかめ太から引き継いでいるため、エラーは出なくなった。しかし、「走る」メソッドはかめ太が実行しているため、かめ子は動かず、かめ太が動いている。


 エラーは出なくなりましたが、かめ子は動いていません。どうしてでしょうか?
 それは「走る」というメソッドを定義したときに  かめ太:走る=「|x|かめ太! (X*歩幅) 歩く」。 とかめ太に歩かせているからです。メッセージを受け取ったかめ子に実行させるには かめ太:走る=「|x|! (X*歩幅) 歩く」。と「かめ太」を消してみてください。メッセージを受け取るオブジェクト(レシーバ−)を省略するとそのブロックを実行しているオブジェクト(つまり、メッセージを受け取った本人)が実行をするようになります。目の前にいる人にものを頼むときは主語を省略して「○○しておいて。」とだけ伝えるのと似ていますね。
 メソッドを他のオブジェクトに継承して、プログラミングをすることはよくありますので、通常、メソッドの定義をするときはレシーバーを省略して書くようにします。

//タートルオブジェクトの生成
かめ太=タートル ! 作る。
かめ子=かめ太 ! 作る
かめ子! "ayumiAka.gif" 変身する。

//かめ太に「走る」能力を追加
かめ太:歩幅=2。
かめ太:走る=「|x|! (X*歩幅) 歩く」。
かめ太! 50 走る。
かめ子! 100 走る。


*「走る」というメソッドのレシーバーは省略されているので、メッセージを受け取ったかめ子本人が実行している。



 6-4.衝突メソッド


 ドリトルにはオブジェクトが動いたときに他のオブジェクトにぶつかると「衝突」メソッドが実行されるようになっています。
 これを使って、ぶつかったかどうかを検知したり、ぶつかってから、どうするかを指定することができます。
 通常のメソッドと同様に「オブジェクト:衝突=」で定義します。

//タートルオブジェクトの生成
かめ太=タートル ! 作る。

//図形オブジェクトの生成
かべ=かめ太! ペンなし −300 200 位置 ペンあり 600歩 歩く 90度 左回り 20 歩く 90度 左回り 600歩 歩く 閉じる 図形にする。

//タイマーオブジェクトの生成
かめ太のペース=タイマー! 作る。

//衝突メソッドの定義
かめ太:衝突=「! 90度 右回り」。

//実行部分
かめ太! ペンなし 中心に戻る ペンあり。
かめ太! 45 左回り。
かめ太のペース! 0.5秒 間隔 15秒 時間「
かめ太! 10歩 歩く。
」実行。

*壁にぶつかると方向を変えます。


 衝突メソッドはアニメーションなどのプログラムではとても便利です。
 ぜひ、使ってみてください。

次へ

前へ


(c) 2002 長谷川元洋 All rights researved. ghase@logob.com