在构造函数,析构函数或方法中,我可以找出创建类的命名空间,因此我可以在其他类中调用card
而不是将其编码为blackjack::card
吗? / p>
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]
}
}
}
...
}
}
答案 0 :(得分:3)
你已经知道了这一点,而且我实际几乎总是这样做,因为它直接而简单。 (它是“选项0”,因为它没有提出问题。)
uplevel
你可以这样做:
lappend cards [uplevel 1 [list card new $suit $value]]
但这取决于从正确的命名空间调用deck new
。
如果我们假设这两个类在同一名称空间中:
constructor {} {
set cardClass [namespace qualifiers [self class]]::card
# ...
lappend cards [$cardClass new $suit $value]
# ...
}
namespace path
如果你添加到对象的路径(NB:必须在构造函数中基于每个对象完成),那么你可以简单地引用另一个类:
constructor {} {
namespace path [list {*}[namespace path] ::blackjack]
# ...
lappend cards [card new $suit $value]
# ...
}
这里要注意的主要事项是TclOO设置了一个非平凡的默认namespace path
(您认为next
和self
来自哪里?)
您还有另一种选择,那就是使用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
实例这个很棘手!
constructor {} {
oo::class create card {superclass ::blackjack::card}
# ...
lappend cards [card new $suit $value]
# ...
}
这也意味着当牌组消失时,卡片将被自动删除;你不需要在析构函数中销毁它们(因为它们的实际类将被自动删除,并且会杀死实例)。这可能是也可能不是你需要的。 (它确实为UML组合关系建模提供了一种好方法; TDBC在内部使用了一个变体来将语句与连接和结果集与语句相关联。)