RealBasic University

このコラムはStone Table Softwareのオーナーであり、またREALbasic Developerの編集者でもあるMarc Zeedar氏により書かれたものを、著者の許可を得て翻訳したものです。この翻訳はHREM Researchにより提供されています。この日本語版へのご意見はRBU-Jまでご連絡下さい。

URL: http://www.applelinks.com/rbu/082/
INDEXに戻る

OOP University:パート 6

前回は、クラスインスタンスの違いについて検討しました:今回は、そのレッスンを、実用的な例題を用いて続けていきます。

新たなものの見方

理解の早い人は、前回のレッスンのオブジェクトについての説明により、REALbasicで最も混乱しやすいコマンドの一つであるnewコマンドについて、(最終的に!)明瞭になったことでしょう。

ある時は、それを使用する前に"new"しなければならず(new dateのように)、またある時は、その必要がないことに気付いたことと思います。どうして、ある時は必要で、またある時は必要がないのでしょう?

説明は単純です。catObjectClassclassなので、オブジェクトとしては存在しません。だからnewは適用しないのです。しかし、catObjectClassのインスタンスを作成したならば、そのインスタンスは"new"しなければ機能しないでしょう。(newコマンドはオブジェクトのメモリーを予約します:家がなければ、オブジェクトは存在することができません!)

したがって、次のようなコードを書くことがよくあるでしょう:

  
dim mayhemInstance as catObjectClass

mayhemInstance = new catObjectClass
mayhemInstance.legs = 4
mayhemInstance.mammal = true
mayhemInstance.species = "Tabby"
mayhemInstance.theColor = "Yellow"
mayhemInstance.thePicture = mayhem

しかし、ここに例外があります:ウィンドウにドラッグされたオブジェクトは、既に"new"されています――要するに、REALbasicは先を見越して、そのステップを自動的に行うのです。listBoxcanvas、あるいはウィンドウに置いた他のコントロールを"new"する必要がない理由は、そこにあります。(しかし、コントロールを動的に作成したならば、それを自分でnewしなければなりません。)

詳細

ウィンドウ・オブジェクトが自動的にインスタンス化されなければ、プログラムは一つ目のウィンドウを開く前にクラッシュしてしまうでしょう。なぜならば、ウィンドウを開くことは、そのオブジェクトを見ることだからです。考えて見ましょう:ウィンドウを描画するためには、ウィンドウにはオブジェクトがなければいけません。描画するには、ウィンドウ内を調べて、オブジェクトが一つでも存在しなければ、ウィンドウは存在しないオブジェクトにアクセスすることになります。よって、プログラムはすぐさま、nilObjectExceptionエラーで強制終了します。なんということでしょう!

さらに悪いことに、このエラーを修正するにはどこを探せばいいのでしょう?結局のところ、これは特定ラインのコードに起因しません。このようなものを探し出して、修正するのは、想像するだけで恐ろしいことです。だからREALbasicは、ウィンドウ上のオブジェクト(ウィンドウ自身も同様)を自動的にインスタンス化("初期化")するのです。しかし、それ以外のケースでは、それは我々に委ねられています。

猫のオブジェクトのデモ

今週は、いままで話してきたことについて、猫のシステムを使用した簡単なデモ・プロジェクトを用意しています。いくつかの違いに気付くかもしれませんが、一般的に私がいままで述べてきたことと同じです。このプロジェクトでは、猫のボタンをクリックすると、対応する猫の写真を表示します。

我々はこのプロジェクトを、これからのレッスンで拡張していきます。例えば、現在は、猫はあまりオブジェクト指向的ではありません:彼らは自分をどのように描画するかを知るべきでしょう。我々は、それを後ほど行っていきます。

注意してほしいのですが、プロジェクトは実行すると、デフォルトではクラッシュするようになっています:どうしてなのかを考え、それを修正してください!(コメントの中で、どのようにするかを述べているので、とても簡単です。:-)しかし、そうすることで今回のレッスンの補強になるでしょう。

今週のチュートリアルの完全なREALbasicプロジェクト(リソースを含む)を手に入れたい場合は、ここからダウンロードしてください。

インスタンスの参照

さて、REALbasicの動作から、(前回の例題の)mayhemInstanceは実際のcatObjectClassのインスタンスであると、間違って信じてしまうかもしれません。実際は、そうではありません。オブジェクト自身のインスタンスは、メモリーのどこかに保存されている構造体です。どこであるかは重要ではありません――REALbasicは舞台裏で、込み入った仕事をこなしています。

実際の変数であるmayhemInstanceは、本当はインスタンスではなく、それはインスタンスへの参照です。それは何を意味しているのでしょうか?

あなたが伝統的なプログラミング言語に慣れ親しんでいるならば、ポインターを扱ったことがあるでしょう。ポインターとは、メモリーの特定場所への単なるレファレンスです。コンピュータにとっては、いかなるメモリーも同じものであると忘れないでください――長い一連のメモリー・アドレスのリストがあるだけです。数百万(あるいは数十億)におよぶ私書箱を所有している、巨大な郵便局を想像してください。ポインターは、私書箱を示す番号と同じものです。

ほとんどのプログラミング言語は、ポインターのデータ型を持ちます。REALbasicには無いように思われますが、実際にはあります:どんなオブジェクトのデータ型も、実際はそのオブジェクトへのポインターです。それが、オブジェクトがnilをとりうる理由です――nilとは、nilポインターという意味で、ポインターは空を指しているのです。

どうして私は、わざわざこれを説明するのでしょうか?なぜなら、それが重要だからです。REALbasicは素晴らしい言語で、洗練された言語の背後に、ポインターの見苦しい詳細を隠す方法は見事です。しかし、例えが崩れ落ちるとき、それは問題を引き起こします。

例えば、このようなことをいままでに試したことはありますか?

  
dim d1, d2 as date

d1 = new date
d2 = new date

if d1 = d2 then
beep
end if

上のコードは、あなたがどのように考えていようとも、その様には機能しません。あなたは二つの日付オブジェクトを比べられると考えています――しかし、d1d2は日付オブジェクトではありません!それらは、実際のオブジェクトへのただの参照(ポインター)であることを忘れないでください。

私書箱の例えに戻りましょう。システムがd1によって参照される日付オブジェクトを私書箱1074番、d2によって参照される日付オブジェクトを私書箱4383番に決めたとしましょう。よって、上のコードは次のことを意味しています:

  
if [私書箱1074番へのポインター] equals [私書箱4383番へのポインター] then...

もちろん、これはまったく意味をなしません!

この比較問題を解決する実際の方法は、次のようにすることです:

  
dim d1, d2 as date

d1 = new date
d2 = new date

if d1.TotalSeconds = d2.totalSeconds then
beep
end if

これはインスタンスの参照ではなくて、実際のスカラー・データ型(double)を比較しているので、これでうまくいきます。

インスタンスの参照と、実際のオブジェクトのインスタンスを混同する問題は、次のような間違ったコードの原因にもなります:

  
dim object1, object2 as myObject

object1 = new myObject
object2 = new myObject

object1.text = "No text yet"
object2 = object1

またしても、プログラマーはREALbasicでオブジェクトが動作する方法を誤解しています。object1object2の参照は、オブジェクトではなく、ただのポインターです。object2 = object1と宣言することは、object1.textobject2.textへコピーするのではなく、object2に、object1と同じ私書箱を指せと宣言しているのです!

実用的な例を用いて、これをもっと詳しく見てみることにしましょう。

私は簡単なプロジェクトを作成しました(ここからダウンロードできます)。これは、theContentsと呼ばれる一つの文字列の属性を含んでいる、myClassと呼ばれるカスタム・クラスを使用します。プログラムが実行されるとmyClassの二つのインスタンスが作成され、メイン・ウィンドウにその内容が書き出されます:

これで遊んでみてください:左側のテキスト欄の内容を変更して、右側の対応するボタンを押すと、そのオブジェクトの内容が更新されます。

しかし、あなたが"Copy"ボタンをクリックすると(単にanObject2 = anObject1を実行します。それはオブジェクトをコピーするのではなく、オブジェクトへ参照をコピーするだけです)、インスタンスの更新された内容は、常に同じです。

これが起こる理由は、今は一つのインスタンスしかないからです!二つの参照があったときは、それぞれは異なる私書箱(インスタンス)を指していました。"Copy"ボタンをクリックしたあと、依然二つの参照がありますが、それらは同じ私書箱(インスタンス)を指しています!よって、二つの参照は同じ内容を持つようになり、同じように作用するのです。

詳細

上記で、私はインスタンスはたった一つしかないと指摘したことに気がつきましたか?我々は、二つのインスタンスで始めたのではなかったのでしょうか?

ええ、そうです。しかしREALbasicは水面下で、複雑なメモリー配分作業のすべてを処理しているので、二つの参照変数に同一のもの(二つとも一つのインスタンスを指す)を指すようにさせると、すぐに残り一つのインスタンスは何も指定していないことが判ります。二番目のインスタンスは参照するものが何もなく、それゆえ再びそこへアクセスする方法はありません(それが参照していた私書箱は何であったか、実際に知ることはできません。残っているものは参照変数のみです。"私書箱"を一度変更してしまったら、元の参照を再び指すことはありません)。したがって、REALbasicは、それをメモリーから削除することによって、インスタンスが使用していたメモリーを解放します。

この種のメモリー管理は、"ガーベッジ・コレクション"(インスタンスを参照できないものは、使われることがないのでガーベッジ(ごみ)です)と呼ばれます。実際には、オブジェクトの最後の参照にnilを参照するよう設定することで、オブジェクトを削除するようにREALbasicに指示できます。しかしこれは、参照がオブジェクトの最後の参照の場合のときです:他の変数や属性がオブジェクトを参照している場合は、オブジェクトはまだ生きていて、自動的に削除されることはありません。

RBUの大部分では、私はインスタンスの参照をインスタンスと言っています。それは、より簡単で、90%の場合はうまくいきます。ただし時折、 あるオブジェクトを他にコピーできると考えてしまう時のように、例えは上手くいきません。ですからインスタンスの参照とインスタンスの違いを理解することは、非常に重要です。

ふうっ!たくさんの難しい課題がありました。あなたがこれらを適切に理解されていることを望みます。我々は、今まさに、重要な局面に来ています。

次週

オブジェクトに、機能を追加します!

ニュース

Dong Liさんのご支援により、中国語のRBUのウェブサイトが運営されています。サイトは、新しいアドレスに移動しましたので、ブックマークの更新をお願いいたします!

ところで、私は日本語や中国語は読めませんが、そのサイトは、Mac OS Xではクールに見えます:外国語のサイトに訪れるときに、よくある文字化けに悩まされることなく、日本語と中国語は正確に表示されています。それはとても素敵です。確認してみましょう!

Letters

今回はJudyさんから、単純ですが興味ある質問をいただきました。彼女の手紙はこうです:

単純な質問があります……もし、答えがあれば、それはとても簡単だと思います!:)

まずは……私はおよそ一年間、REALbasicを使っています。そして二つの立派な(そう思っているのですが…)プログラムを完成させました。

そして今夜、これだけ使用してきたにもかかわらずに、私はプロジェクトを保存するのに二つの方法があることに気がつきました!(私が混乱しているのは二つです)

REALbasicドキュメントとして保存(これがデフォルトのようですので、今まではこれで保存されていました)するか、あるいは標準プロジェクトとして保存(これは今までずっと、私が使ってきたと思っていたものです)

この違いは、いったい何なのでしょうか?

よろしくお願いします!

Judy

Judyさん、興味ある質問です!正直に言うと、私は答えを知りませんので、REAL Software社のエンジニアであるJoe Strout氏に尋ねました。彼はREALbasic Developerの編集委員で、多大な貢献をしています。彼はこの質問について次のように答えました:

"REALbasicドキュメント"は、単なる"デフォルト・フォーマット"を意味しています。その三行下のポップアップで区切られている部分は、特定のフォーマットです。読者の方は正しく、デフォルト・フォーマット(要するに"REALbasicドキュメント")が"標準フォーマット"です。

これで解決しましたね!


RBU-Jの通知サービス!コラムが発表されるたびに日本語版REALbasic Universityのお知らせの emailがあなたに届きます。登録・削除は ここ から。

INDEXに戻る