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