In <B5695A02.1D03%khosokawa@....com> (Jun.11 2000 15:02 JST),
``[XP-jp:00522] Re: XP Installed26 Part1 Test-first, by Intetion'',
khosokawa@....com says:
=
= 補足ですが、
=
= class Sum extends Object {
= // ...
= }
=
= という事ですね。
「そうです」... といっていいものかどうか...
Javaでは、
class Sum extends Object {...}
は、単に
class Sum {...}
を冗長に書いただけのものです。Smalltalkでは「すべてがメッセー
ジ式」といえますから、クラスの定義する方法は、クラスオブジェク
トにメッセージを送ることによって実現されるわけです。
たとえば、Squeakのばあいには、
AClassObject
subclass: #MyClass
instanceVariableNames: 'foo bar baz '
classVariableNames: ''
poolDictionaries: ''
category: 'Kenn-Test'
のように、``AClassObject''というクラスオブジェクトに
``subclass:instanceVariableNames:classVariableNames:poolDictionaries:category:''
というメッセージを送ると、新しいクラスオブジェクト(上記では
``MyClass'')がシステム内に生成されます。
クラスをあくまでも静的に定義するJavaとは、構文だけでなくセマン
ティックスがまったく違います。
= 教えて下さい。「Object」が「new」を受け取って、インスタンスを返すのでしたっ
= け?
クラスオブジェクトに``new''メッセージを送ると、インスタンスオ
ブジェクトが返って来ます。また、インスタンスオブジェクトに
``new''を送ると、エラーになります。
aaa := MyClass new.
aaa inspect.
とWorkspaceで記述して、doitすると、無事inspectorウィンドウが開
きます。aaa にはインスタンスオブジェクトが束縛されている事がわ
かります。しかし、
iii := aaa new.
をdoitすると、``MessageNotUnderstood: new''と言われます。
= ここは、「name:amount:」の定義をしている部分ですね。「setNameAndAmount()」は、
= 後で登場させて、定義の中身だけ、直訳した方がいいように思います。
=
= Sum aNewSum = new Sum;
= aNewSum.setName(aString);
= aNewSum.amount(aNumber);
``setName:amount:''は、これでひとつのメソッドなんです。これも、
構文上の大きな違いですね。Javaのほうのメソッド名として
``...And...''を間にいれたのは、中途半端な意訳だったかもしれま
せん。
あらためて順番に説明すると、
self new
で、Sumの新しいインスタンスオブジェクトが返されます。ここでの
selfですが、生成側では
aSum := Sum name: 'a' amount: 1.
のように、クラスオブジェクト``Sum''にメッセージを送りますから、
レシーバはクラスオブジェクト``Sum''、selfはSumです。
つづいて、
self new
setName: aString amount: aNumber
と、``setName: aString amount: aNumber''メッセージを送ってい
ます。レシーバはSumのインスタンスオブジェクト(無名)です。
そのメッセージに対する応答が、
^self new
setName: aString
amount: aNumber
となって、このメソッド(name:amount:)の応答になります。
単一のメッセージ式であることを重視して直訳するなら、こんな感じ
でしょうか。
return (new Sum()).setNameAndAmount(aString, aNumber);
なので、これはコンストラクタというよりはむしろファクトリメソッ
ドに近いものです。コンストラクタとして意訳するなら、素直に、
public Sum(String aString, int aNumber){
name = aString;
amount = aNumber;
}
で十分かもしれません。
= ところで、原文の「Constructor Parameter method」は、どういうものなのでしょう
= か?
これは、彼らの用語だと思います。
「リファクタリング」の邦訳をお持ちなら、173ページの、自己カプ
セル化フィールドを使用する場合のコンストラクタの例が参考になる
のではないでしょうか。
IntRange(int low, int high){
initialize(low, high);
}
private void initialize(int low, int high){
_low = low;
_high = high;
}
このinitialize()が良く似ています。(もっとも、voidでもprivateで
もありませんが)
「生成して初期化する」処理から「初期化する」処理を括り出すこと
によって、たとえば、「そのインスタンスを初期化しなおしたい」と
いうような要求や、「サブクラスでちょっと異なった初期化をしたい」
というような要求に答えることができるとおもいますが、つまり、そ
ういう実装を彼らは習慣としているのでしょう。
-.- . -. -.
Ken Nakagaki (kenn@....nu is NOT for private E-Mail)
「人は船ではない。人は会社ではない」-- Gerry Spence