Index: [Article Count Order] [Thread]

Date:  Sun, 11 Jun 2000 22:54:22 +0900
From:  "Ken N." <kenn@....nu>
Subject:  [XP-jp:00523] Re: XP Installed26 Part1 Test-first, by Intetion
To:  extremeprogramming-jp@....jp (extremeprogramming-jp ML)
Message-Id:  <200006111354.WAA24861@....nu>
In-Reply-To:  Your message of "Sun, 11 Jun 2000 15:02:05 +0900".    <B5695A02.1D03%khosokawa@....com>
Posted:  Sun, 11 Jun 2000 22:54:06 +0900
X-Mail-Count: 00523

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