複数のオブジェクトを格納するオブジェクトのことをコレクションという。
a := Array new: 5 (大きさ5の配列を作る。) (Array はクラス名。a は配列のインスタンスを指す。) |
a at: 1 put: 'one' ( at:〈番目〉put:〈置く物〉という書式) a at: 2 put: 'two' a at: 3 put: 300 |
a at: 1 ( at:〈番目〉という書式)(ALT + p を押すと置かれている物が返される。) a at: 2 (ALT + p を押す) a at: 3 (ALT + p を押す) a at: 4 (ALT + p を押す。何が返るかな?) |
b := Bag new (空のバッグを準備する。) (Bag はクラス名。b はバッグのインスタンスを指す。) |
b add: 'apple' (add: で、バッグにオブジェクトを入れる) b add: 'orange' b add: 'melon' |
b do: [: f | (do: は、バッグの要素の1つずつに、ブロックの処理を実行) Transcript show: f ; cr] (その要素は、変数 f が指している) |
今日の演習も、新しいプロジェクトの中で実行しよう。
星の図形を表示する練習では、図形の消去が問題であった。そこで、表示した図形を管理するようにしよう。そして、まとめて消去ができるようにしよう。以下はワークスペースで実行する。
(1) バッグを準備しよう。
morphBag := Bag new |
(2) 星を作る手続きをブロックにまとめよう。
newStar := [: mb | | s | s := StarMorph new. mb add: s. s openInWorld] |
(3) 試しに星を作ってみよう。
a := newStar value: morphBag a position: 100@200 a := newStar value: morphBag a position: 80@220 a := newStar value: morphBag a position: 120@240 |
(4) 星を消そう。
morphBag do: [: s | s delete ] |
ちなみに、再表示ができる。
morphBag do: [: s | s openInWorld ] |
配列やバッグのインスタンスに使用できるメッセージの例を示す。
要素の個々について処理をするメッセージ(do:の仲間)には、たとえば、次のものがある。
次のようにして、1から10までの整数を要素とする配列を変数 a で指すことにする。変数の中身を確認するには、inspect を使おう。
a := #( 1 2 3 4 5 6 7 8 9 10 ) |
(1) 変数 a の各要素を2倍したものを集めた配列を作り、変数 b で指すことにせよ。
(2) 変数 b の中から、3の倍数を集めた配列を作り、変数 c で指すことにせよ。
(3) 変数 b の中から、3の倍数でないものを集めた配列を作り、変数 d で指すことにせよ。
(4) 変数 c の要素を x 、変数 d の要素を y として、x -+ y を要素とするバッグを作り、変数 e で指すことにせよ。
(5) 変数 e のバッグは、サイズが 21 であることを確認せよ。
(6) 変数 e から、負の値となるものを何か1つ返せ。
星の図形の他に、楕円の図形や、長方形の図形がある。これらのクラス・オブジェクトは、EllipseMorph や RectangleMorph である。これらには、StarMorph と同じ操作ができる。すなわち、「new」でインスタンスを作り、「position:」で位置を決めて、「openInWorld」で画面に表示させたり、「delete」で画面から消したりすることができる。
オブジェクトを作る側からみると、クラスが異なると、処理の細かい点で違いがあるので、同じメソッド名でも、オブジェクトごとにプログラムコードを書いている。
ポリモーフィズムとは、「同じメッセージを送っても、オブジェクトによって処理が異なること」である。
オブジェクトを使う側からみると、直感的にプログラムを書いたり読んだりできるというメリットがあるが、むしろ、プログラムの条件選択のコードを沢山書かなくても良くなるというメリットのほうが大きい。
星、楕円、長方形などの図形を入れるバッグを作り、図形を操作してみよう。
(1) 変数 morphBag がバッグのインスタンスを指すようにせよ。
(2) moprhBag に、星の図形のインスタンスを一つ加えよ。すなわち、「morphBag」に「add:」のメッセージを送るのだが、第1引数が「StarMorph new」の結果である。
(3) morphBag に、もう一つ星の図形のインスタンスを加えよ。
(4) morphBag に、楕円の図形のインスタンスを2つ加えよ。
(5) morphBag に、長方形の図形のインスタンスを3つ加えよ。
(6) morphBag のサイズが、7であることを確認せよ。
(7) morphBag の要素のそれぞれに異なる座標を与えたい。1つ目の図形は座標が(150,300)、2つ目の図形は座標が(180,320)、3つ目の図形は座標が(210,340)、…と、x 軸方向に 30 ずつ、y 軸方向に 20 ずつ増やしながら、座標を与えよ。
(8) moprhBag の各要素を表示(openInWorld)させよ。
C言語で、練習3と同様のプログラムを書くと、どのようになるか考えよう。
もし、星図形が構造体 struct star_morph で定義され、楕円図形が構造体 struct ellipse_morph で定義されているとすると、バッグはどのように実装すれば良いか?
もし、星図形の位置を設定する関数が、void star_morph_position( struct star_morph *sm, int x, int y ); であり、楕円図形の位置を設定する関数が、void ellipse_morph_position( struct ellipse_morph *em, int x, int y ); であるとする、(7)での座標指定はどのように実装すれば良いか?