3

私が正しく理解した場合、抽象クラスは少なくとも1つの抽象メソッドを持つものですか?

さて、それが抽象的であれば、そのクラスのインスタンスを作成できないはずですか?

同様に、 saidAbstは抽象クラスの名前です (抽象メソッドが含まれているため)。

a := Abst new.

違法であり、エラー/例外をポップアップする必要がありますか? または、ここで問題が発生するはずです。

a := Abst class new.

?

更新: 提案されているように、ユーザーがクラスのインスタンスを作成できないようにする次のメソッドを作成しましたが、機能しません:

makeAbstract: aClass    
    aClass compile: 'new
                ^ self subclassResponsibility'.
4

5 に答える 5

11

スモールトークへようこそ!Smalltalk の優れた点の 1 つは、開発者を信頼していることです。開発者は、その信頼がもたらす力から恩恵を受けます。したがって、「できない」や「違法」などの言葉はほとんど当てはまりません。

他のほとんどのものと同様に、Smalltalk の抽象クラスは、厳格な法則というよりも提案/ポインターに似ています。探している 2 つの手がかりは、#subclassResponsibility と #shouldNotImplement です。これら 2 つのメソッドは、特定のメソッドを含めるかどうかにかかわらず、サブクラス作成者にとって手がかりになります。送信者に画像の例を確認してください (常に質問の出発点として最適です)。

上記のように、「抽象」は実際にはメソッドごとであるため、例はエラーを生成しません (#subclassResponsibility または #shouldNotImplement が initialize.

2 つの小さなこと:

  • クラス名は Smalltalk では大文字で表記されるため、abst ではなく Abst になります。
  • グーグル検索は大いに役立ちます。「smalltalk 抽象クラス」の上位 4 つのリンクのうち 3 つだけで十分でした (特にこれは適切に見えました)。

更新:クラスのユーザーにインスタンスを作成してはならないことを通知したい場合(以下のコメントのように)、次のように書くことができます:

Abstract>>new
    ^ self subclassResponsibility.

すると「Abstract new」→エラーですが、「AbstractSubclass new」でOKです。

AbstractSubclass が抽象メソッドをオーバーライドしたという保証はまだありませんが (#new ではありませんが、そもそもインスタンス化を防止したい原因となったものです)、実際にはこれは問題になりません。本当に必要な場合は、おそらく #initialize にチェックを入れて、インスタンスのメソッドが #subclassResponsibility を呼び出さないようにすることができますが、正当な理由がない限り気にしないでください。

更新 2: クラスを抽象化するためのユーティリティ メソッドは次のようになります。

Class>>makeAbstract

    self class compile: 'new
                ^ self subclassResponsibility'.
于 2011-05-02T11:35:15.547 に答える
3

Smalltalk では、抽象クラスをインスタンス化するだけです。抽象メソッドを呼び出さない限り、機能します。不足しているメソッドを実行時に実装したい場合があります。

于 2011-05-02T11:38:01.163 に答える
3

はい、抽象クラスには少なくとも 1 つの抽象メソッドが必要ですが、いいえ、そのクラスのインスタンスを作成することはできます。

あなたがすべきことは、インスタンスを作成してメソッドを呼び出すことができる抽象クラスから継承する具象クラスを作成することです。

Smalltalk の抽象メソッドには、それらとクラスを抽象化する特定の実装があります。

method
    self subclassResponsibility

これは、サブクラスがこのメソッドをオーバーライドし、具体的な実装を提供する必要があることも意味します。

subclassResponsibility に関するエラーが表示された場合は、コードが抽象クラスのメソッドを呼び出したか、サブクラスがメソッドの実装を提供していません。

于 2011-05-02T11:38:59.507 に答える
2

(修正された) "new-blocker" は、具象サブクラスに若干の不便をもたらします: newを再定義する必要があり、継承されたスーパークラスの新しい機能を利用できません。インスタンス化しようとしているのが本当に抽象クラスであるかどうかをチェックする小さなガードでこれを回避できます。

AbstractClass class >> new
    self == AbstractClass ifTrue:[
        ^ self abstractClassInstantiationError
    ].
    ^ super new

(ここで同一性比較に注意してください。これは、複数の抽象クラスを積み重ねた場合でも機能します)

于 2012-11-29T08:24:06.937 に答える
2

Pharo By Example 本を読むことをお勧めします。ここで見つけることができます: http://pharobyexample.org/ 興味深いものがたくさんあります。開いた本で、無料で、pdf をダウンロードできます。実際、あなたが求めていることは、第 5 章の 88 ページで説明されています。

于 2011-05-02T12:44:02.643 に答える