2012-06-03 11 views
6

私はSmalltalkの基礎を学んでいます。サブクラスのメソッド内でスーパークラスからメソッドを呼び出すために使用されているsuperキーワードがあります:クラスメソッドの "super"キーワード

Object subclass: # A 
    test 
     ^1 

A subclass: # B 
    test 
     ^2 
    callSuper 
     ^super test 

のでB new callSuper1に評価されます。

OK。それは明らかです。

だから今、私はBクラスのクラスメソッドの束を定義しています:

createNew1 
    ^super new 
createNew2 
    ^self new 
create 
    ^self 
createSuper 
    ^super 

を彼らはsuperキャストではないことを私に示してa Ba BBとエラー(にそれぞれ評価サブクラス化するが、メッセージディスパッチャのようなもの)。

というキーワードにもかかわらず、Bクラスのインスタンスが表示されるのはなぜですか? a BBオブジェクトの違いは何ですか? Bオブジェクトは、Bという特殊なsingletoneインスタンス(staticの属性が他の言語でも実装されているようなもの)だと思い始めましたが、それでもまだチェックしました。クラスはBで、サブクラスはAです。

クラスメソッドでsuperキーワードのセマンティクスは何ですか?オブジェクトメソッド内のセマンティクスとどのように違いますか? selfクラスメソッドの中で呼び出すことで得られるオブジェクトは本当ですか?

答えて

1

他のすべての回答が技術的に正しいにもかかわらず、私はこれで自分でこれに答えるつもりです。それは私がメタクラスについて知っていて、私の頭にsuperの意味があるように思えますが、私はまだ予期しない結果を得ていました。

それがわかります私はSmalltalkのの継承の基礎とメソッドの呼び出し方法を誤解しています。私はそのようなコードのためにそれを考えていた

...

Object subclass: #A 
    test 
     ^'A' 
    getTest 
     ^self test 

A subclass: # B 
    test 
     ^'B' 
    runTest 
     ^super getTest 

は...表現B new runTest'A'に評価されます - スーパークラスからメソッドがupcastedオブジェクトに評価され、ことを意味します。

しかし、そうではありません。

は、それは何のアップキャストがありませんので、'B'に評価されていますし、私たちは、スーパークラスのメソッド内の任意のメソッドを呼び出しているとき - 検索では、オブジェクトの実際のクラスで開始し、ない方法を検討し、そこからクラスが来ます。 classessのいずれかにnewを定義していないながら、^self new^super newを呼び出した結果

は、同じ効果を持っている - それらの両方がselfのコンテキストで行動のnew実装を呼び出すことで終了するので。

+0

C#に精通しているならば、すべてのSmalltalkメソッド(インスタンスまたはクラス)を仮想として宣言していると考えるとすべてが理にかなっています。 –

+0

"式B new runTestは 'A'に評価されます"いいえ!あなたは実際にこのコードを評価しているのですか、まさに思考実験をしていますか? Smalltalkの大きな利点の1つは、実験を簡単に行うことができることです。 「B new runTest」を評価すると、「B」が返されることがわかります –

+0

@SeanDeNigris英語が不十分で不明なこともありますが、「A」と評価されていると思っていました。事実、それは「B」(次の段落で書かれている)と評価されます。これを編集して明確にしようとします。 –

4

selfおよびsuperは、常に同じオブジェクト、現在の受信機を参照します。唯一の違いは、selfが、メソッドが定義されているスーパークラスの受信者のクラスで送信する次のメソッドの参照と、superの検索を開始することです。

詳細については、第5章のPharo by Exampleを参照してください。

+0

を定義します。しかし 'new'がA''で定義されているので、なぜ '^スーパーnew'があるため' A'オブジェクトを返すされていないのであれば、あなたはコースの場合を除きB
のインスタンスを作成しますそれは 'B'クラスのオブジェクトの中で呼び出されますか?あるいは、私はちょうど 'new 'の意味論が何であるかを完全に理解していないでしょうか? –

4

最初の例に対するあなたの答えは間違っています。 B new callSuperは1を返します。ルーカスはあなたにスーパーの意味論の正確な定義を与えました。これは基本的に 'self'のエイリアスで、送信されたメッセージのメソッドルックアップを変更します。 self messageは、受信者クラスのメソッドの検索を開始します。super messageは、super message式を含むメソッドを定義するクラスのスーパークラスの検索を開始します(この場合、受信者のクラスは関係ありません)。

super newself newは、どちらの場合でも最も近いメソッド定義であるため、同じメソッド(ビヘイビア階層のどこかで定義されています)を呼び出すことになります。ただし、createNewメソッドの名前をnewに変更した場合、new ^self newは無限ループになりますが、new ^super newはBehaviorメソッドを呼び出します。

+0

ああ。それはタイプミスでした。私は聞いている間頭に「1」を持っていました。編集されました。 –

3

selfとsuper同じものを意味するかどうかをクラスまたはオブジェクトでは、クラスオブジェクトなので...

#createNew1 &#createNew2同等です。 Lukasが説明したように、superは単に「クラスの代わりにスーパークラスでメソッドの検索を開始する」ことを意味します。AまたはBのいずれかで#newを定義していないので、スーパークラスを参照して、AまたはBで動作するかどうかにかかわらず、動作>>#newを見つけます。#basicNewを呼び出すことで新たに起動します。 Bの新しいインスタンス(すなわち「a B」)。

#create & #createSuper、あなたは何も見ていないので、自己とスーパーは同じ意味で「現在のオブジェクトを返す」という意味です(後者については何の誤りがありますか?)。今、この部分は混乱しています。 Smalltalkのすべてがオブジェクトなので、クラス自体も含まれます。したがって、このコンテキストでは、「現在のオブジェクト」はメタクラス「Bクラス」の唯一のインスタンスであるBです。あなたが本当に理解に興味があるなら、私はPharo By Exampleの第13章を繰り返し読んで、それが意味をなさないまで(私はまだその点を叩かなかった、笑)。

0

はい、私はあなたが今理解だと思う...
あなたはBクラスから^スーパー新を送信すると、あなたはまだBクラスにメッセージを送って、それはメッセージが(スーパー新)であることだけだ...
あなたは

A class>>new 
    ^A basicNew 
関連する問題