
このコラムはStone Table Softwareのオーナーであり、またREALbasic Developerの編集者でもあるMarc Zeedar氏により書かれたものを、著者の許可を得て翻訳したものです。この翻訳はHREM Researchにより提供されています。この日本語版へのご意見はRBU-Jまでご連絡下さい。
URL: http://www.applelinks.com/rbu/084/前回のレッスンでは、REALbasicがどのようにオブジェクトを扱うかに特に注意を払いながら、オブジェクトの複製と、パラメータとしてオブジェクトを渡すことについてを学びました。今回は、オブジェクトに実行させる方法を検討していきます。
何も実行する能力がなければ、オブジェクトはただのデータ保存庫にすぎません。要するに、有用でないと言うことです。しかし、オブジェクトに何かを実行できるようにさせると、とても役立つようになります。それをオーバーライド(置換:overriding)というものと結びつけると、かなり役に立ちます。それでは、検討していきましょう。
オブジェクトに何かを実行させるようにするには、そのオブジェクトのクラスにメソッドを追加するのと同じくらい簡単です。ここに、簡単な例があります:

doItと呼ばれるメソッドを含むobjectClassと呼ばれるカスタムクラスがあることに注意してください。pushButton1は、anObject1と呼ばれるクラスのインスタンスと通信し、それにdoItを実行するように伝えます――したがって、ボタンが押されたときには、ビープ音が鳴ります。
このままでも、これはとても柔軟性に富みます――pushButton1はobjectClassについて、doItメソッドがあるという以外は、何も知る必要がありません。我々はpushButton1に手を加えることなく、次のようにdoItに何をさせるかを簡単に変更することができます:
sub doIt()
msgBox "Beep!"
end sub
それはとても便利ですが、それほど強力でもありません(メソッドを直接呼び出すことと何の違いもありません)。しかし、いくつかの種類のオブジェクトがあり、各々が独自の動作をすると想像してみましょう。次のようになります:

いま我々には2種類のdoItがあります。一方はビープ音を鳴らし、もう一方はビープのメッセージを表示します。同じdoItのメッセージを、異なるオブジェクトへ送信する機能は役に立ちます。例えば、window1へcheckBoxのコントロールを追加し、それに"Silent"とラベルを付けましょう。checkBox1のvalue(trueあるいはfalse)に応じて、どちらのオブジェクトと通信するかを変更できます:
if checkBox1.value then
messageObject1.doIt
else
beepObject1.doIt
end if
しかし、これは特に優れたプログラムでもありません。これらのオブジェクトに大きな変更を加えたとしたら、pushButton1のコードも書き直さなければなりません。我々はできるだけpushButton1のコードは簡単なものにしたいのです。理想的には、状況に関わらず、一つのメッセージだけを送信したいのです。
さらにオブジェクトを使いやすくするには、次のようにすることでしょう(二つに分かれたコード枠は、checkBox1とpushButton1のコードを示しています):

これは一つのオブジェクトにすべてを収めることでコードを簡略化し、サイレント機能をオンかオフに決めるsilent属性を、オブジェクトに追加してあります。次の重要なことを学びました:
オブジェクト指向プログラムの重要なコンセプトは、外部コード(オブジェクトの部分ではないコード)を、可能な限り単純化し、普遍的なものにすることです。
その理念は、オブジェクトにおける変更点が、外部コードにまで及ばないことです。例えば上記の例で、ユーザがpushButton1を押したときに実行されることを変更したい場合、オブジェクトのクラスを編集するだけで済みます。pushButton1のコードは変更する必要は全くありません。
これを行うには、外部コードを普遍的なものにすることです。すなわち、それにある特定の動作をさせないようにすることです。2番目の例では、我々はpushButton1にサイレント機能をオンかオフにする決定をさせました。それは、pushButton1がどちらのオブジェクトがどのような動作を行うのかを知っている必要があると言うことです。後になってこれらのオブジェクトを変更する場合、その修正のためにpushButton1に適切な変更を加えなければなりません。その代わりに3番目の例では、pushButton1はオブジェクトにdoItのメッセージを送信するだけです。オブジェクトそれ自身が、どのような動作をするのかを決定します。
3番目の例は、オブジェクト内部で様々な動作を処理する一つの方法ですが、それはOOPの様式には当てはまりません。さらに複雑なオブジェクトでは――単純なsilent属性のオン/オフだけではなく、100の異なる動作があるとしたら――今までのやり方では実用的ではありません。
よりよい処理方法は、オーバーライド(overriding)と呼ばれるOOP概念の長所を利用することです。オーバーライドとは、親クラス(superclass)の動作を定義し直すためのサブクラスの機能です。デモとして、noisyObjectClassとsilentObjectClassと呼ばれる2つのクラスを作成しましょう:

silentObjectClassのsuperをnoisyObjectClassに設定して、それをnoisyObjectClassのサブクラスにします。それは、silentObjectClassでdoItが行うことを再定義しない場合には、noisyObjectClassと同じ動作を行うことを意味します。しかし、silentObjectClassの動作を変更し、その上で呼び出されたオブジェクトがsilentObjectClassの場合には、我々がsilentObjectClassで定義した動作が実行されます。
anObject1のインスタンスをsilentObjectClassに設定してプログラムを実行させると、msgBoxが機能します。それをnoisyObjectClassに設定すると、ビープ音が鳴ります。
最初は、このやり方はまるで逆行しているように見えるかもしれません:以前よりもたくさんの(より複雑な)オブジェクトがあり、もはやその動作を動的に設定することもできません(我々は立ち上げる前にanObject1のタイプを設定しなければなりません)。window1に前もって設定しておく代わりに、インスタンスを動的に作成することができますが、それは複雑さを増します。そしてオブジェクトの動作をその場で変更できるcheckBoxもありません。
しかし、これらの不都合な点は我々の例が簡単すぎることから現れます。オーバーライドは、この場合は必要ありません。この種のプロジェクトでは、前に記した2番目のメソッド[訳注:3番目の例題]を使用するのがベストです。しかし、より複雑な問題では、オーバーライドはほとんどの場合で一番良い方法です。このテクニックの威力を見るためには、もっと複雑な例が必要になります。
次回のレッスンで、シンプルなオブジェクト指向型のお絵かきプログラムを書いたときにそれを取り上げることにしましょう。作成が簡単なのに、とても驚くでしょう!
今回取り上げたプロジェクトの完全なREALbasicファイルを手に入れたい場合は、ここからダウンロードしてください。3つに分かれたプロジェクト(doi1.rb、doit2.rb、doit3.rb)になっているので、様々なメソッドを試してみることができます。
SimpleDrawを制作します!
今週は、Ericさんから素敵なお手紙を頂きました:
こんにちはMarcさん、
私は長年にわたるRBUの読者で、とても気に入っています!
コラム80で、あなたがREAL Software社はデフォルトでAppクラスを含めるべきだと指摘していたことについて、あなたにメールしています。REALbasic 5αをダウンロードしてみれば、その機能が含まれていることにとても喜ばれると思います。
素晴らしいコラムにお礼をするとともに、よいお仕事をこれからもお続け下さい!
Eric
Ericさんありがとう!実際には私はこれに気づいていました。REAL Software社がいつこれを始めたのかは知りませんが(最近になってアルファをチェックしたばかりです)、彼らの処置に喜んでいます。それは初心者にとっても分かりやすいし、そこにあることによっても害があることはありません――仮に使用しないとしても、それなしで作成したRBアプリと何もかわりありません。
ところで、REALbasic 4.5でこの機能を利用したい場合、あなたの作成するすべての新しいプロジェクトに、Appクラス(あるいは別の何か)を追加するための独自のRBプロジェクトのテンプレートを作成することができます。新しいプロジェクトを作成して、そこに追加したいものを何でも入れてください。それはあなたの作成した基本的なアプリの骨格、あるいはあなたがよく使うモジュールやクラスなどでしょう。このプロジェクトを"Default New Project"(引用符は必要ありません)として、REALbasicフォルダー内のStationeryフォルダーに保存します。それ以後は、あなたが新しいプロジェクトを作成(ファイルメニューで"New"を選択)する度に、そのプロジェクトは新しいプロジェクトのテンプレートとして使用されます。とても便利です。
Stationeryのヘルプ文書からの引用です:
Stationeryファイルの名前を"Default New Project"と変更して、REALbasicフォルダーの中のStationeryフォルダーに保存すると、REALbasicはそのプロジェクトを新しいプロジェクトのテンプレートとして使用します。これらの新しいプロジェクトは、"Untitled"となって開かれますが、Stationeryファイルからのクラス、ウィンドウ、その他すべてを受け継いでいます。Stationeryファイルをもとに作成した新しいプロジェクトに加えた変更は、Stationeryファイルに影響は与えません。
RBU-Jの通知サービス!コラムが発表されるたびに日本語版REALbasic Universityのお知らせの emailがあなたに届きます。登録・削除は ここ から。
INDEXに戻る