2

コンストラクタ、デストラクタ、またはメソッド内で、クラスが作成された名前空間を見つけることができるのでcard、他のクラスをハードコーディングする代わりに呼び出すことができblackjack::cardますか?

namespace eval blackjack {

  oo::class create card {
    ...
  }

  oo::class create deck {
    constructor {} {
      my variable cards
      set cards {}
      for {set suit 0} {$suit < 4} {incr suit} {
        for {set value 0} {$value < 13} {incr value} {
          lappend cards [blackjack::card new $suit $value]
        }
      }
    }
    ...
  }

}
4

1 に答える 1

3

オプション 0: 完全修飾名

あなたはすでにこれを知っています、そしてそれは直接的で単純なので、私が実際にほとんど常に行っていることです. (質問をしないので「オプション 0」です。)

オプション1:uplevel

あなたがすることができます:

lappend cards [uplevel 1 [list card new $suit $value]]

ただし、それはdeck new適切な名前空間から呼び出されるかどうかによって異なります。

オプション 2: クラス名手術

2 つのクラスが同じ名前空間にあると仮定すると、次のようになります。

constructor {} {
    set cardClass [namespace qualifiers [self class]]::card
    # ...
        lappend cards [$cardClass new $suit $value]
    # ...
}

オプション 3: オブジェクトの拡張namespace path

オブジェクトのパスに追加すると (注: コンストラクターでオブジェクトごとに実行する必要があります)、他のクラスを簡単に参照できます。

constructor {} {
    namespace path [list {*}[namespace path] ::blackjack]
    # ...
        lappend cards [card new $suit $value]
    # ...
}

ここで注意すべき主なことは、TclOO が自明ではないデフォルトを設定することです(どこから来たとnamespace path思いますか?)nextself

オプション 4: コマンド リンクを作成する

別のオプションがあります。それは、コマンド リンクを使用namespace exportして作成することです。namespace import

まず、関連するクラスを::blackjack名前空間からエクスポートします。

namespace eval ::blackjack {
    namespace export card;   # You probably want to export “deck” as well

    # ...
}

次に、コンストラクターでインポートを行います。

constructor {} {
    namespace import ::blackjack::card
    # ...
        lappend cards [card new $suit $value]
    # ...
}

deckオプション 5:インスタンスに特別なサブクラスを作成する

これはトリッキーです!

constructor {} {
    oo::class create card {superclass ::blackjack::card}
    # ...
        lappend cards [card new $suit $value]
    # ...
}

これは、デッキがなくなるとカードが自動的に削除されることも意味します。デストラクタでそれらを破棄する必要はありません (実際のクラスは自動的に削除され、インスタンスが強制終了されるため)。それはあなたが必要とするものかもしれませんし、そうでないかもしれません。(これは、UML 構成関係をモデル化するための良い方法になります。TDBC は、ステートメントを接続に関連付け、結果セットをステートメントに関連付けるために、これのバリエーションを内部的に使用します。)

于 2013-04-22T09:36:45.430 に答える