よしだです。
#やはり、全体に対してはコメントが書きにくい(論点が不明になって
#しまう。変換した後の文章が「大作」なので…。)ので、部分的な
#コメントにします。
コンストラクタについて:
Javaではコンストラクタの実行順序を考慮しないと行けないと思いま
すので以下のような差があります。
> <Smalltalk>
> === Page 191 Code 3
>
> setName:aString amount:aNumber
> name:=aString
> amount:=aNumber
> </Smalltalk>
> /*
> しかし、実際にはつぎのようなものでも十分かもしれません。
> */
> private /* or protected */ void setNameAndAmount(String aString, int aNumber){
> name = aString;
> amount = aNumber;
> }
Javaでは、ここではprivate以外ではいけません。理由は「オブジェクト生成」
の動作の違いにあります。「初期化」目的のメソッドですので、コンストラクタで
使用されますが、サブクラスでオーバーライドできてしまうと、例えば、以下のよ
うな問題となります。
class Base {
String name_;
Base(String name) {
setName(name);
}
protected void setName(String name) {
name_ = name;
System.out.println(name_);
}
}
class Foo extends Base {
String fooSuffix_ = "Foo";
Foo(String name) {
super(name);
}
/**
* new Foo("名前")の結果が、"名前Foo"となることを期待している
* が、うまく行きません。コンストラクタと生成の順序を考えましょ
* う。
*/
protected void setName(String name) {
/* 自分のインスタンス変数(fooSuffix_)が問題。*/
name_ = name + fooSuffix_;
System.out.println(name_);
}
}
まだ、superのコンストラクタ実行中は、インスタンス変数fooSuffix_が設
定されてないわけです。newというメッセージによって具象オブジェクトが
できてしまってからConstructor Parameter Methodが呼び出される
Smalltalk とは異なるわけです。(実際にはprivateプロトコルに置くので
同様のことを考慮している?かもしれないですが。)
#あまり良い例でないかな。
--
吉田 尚志 steven@....jp