使用TclOO在对象创建中创建vs新建
我正在研究使用TclOO在对象创建中创建vs新建,tcl,Tcl,我正在研究TclOO,发现我们可以使用create或new创建对象。 使用create我们可以提供定制的名称,而使用new则是计算机生成的 #!/bin/bash #\ exec tclsh8.6 $0 $@ ::oo::class create calc { method add { a b } { return [ expr {$a+$b} ] } } calc create c; set t [ calc new ] #
TclOO
,发现我们可以使用create
或new
创建对象。
使用create
我们可以提供定制的名称,而使用new
则是计算机生成的
#!/bin/bash
#\
exec tclsh8.6 $0 $@
::oo::class create calc {
method add { a b } {
return [ expr {$a+$b} ]
}
}
calc create c;
set t [ calc new ]
# Both serves the same purpose here
puts [ c add 3 4 ]
puts [ $t add 1 2 ]
这仅仅是编译器为开发人员提供的对象命名便利吗?另外,如果我更喜欢
new
而不是create
,new
和create
之间的唯一区别就是create
允许您指定要使用的名称,new
为您提供一个新名称。某些类型的对象(特别是类)隐藏了它们的新方法
,因此强烈建议您只创建命名实例-考虑到人们使用类的方式,这在实践中很有意义-但这只是隐藏,如果需要,您可以覆盖它:
oo::define oo::class {
export new
}
如果你不在乎名字,只想让它与其他东西不同,就可以使用new
。这是基本的经验法则
单身汉
使用create
创建其他OO系统可能使用单例的实例也很完美。还有什么比给他们一个你能控制的好名字更独特的呢
寿命管理
我所知道的另一个主要场景是,当您希望将一个对象的寿命绑定到另一个对象时,使用create
更有用。在这种情况下,在另一个上下文中创建对象将把对象句柄放在容器的命名空间中,并在删除容器时自动触发删除:
oo::class create InsideThing {
constructor {} {
puts "Made a [self] that is an InsideThing"
}
destructor {
puts "Deleted a [self] that is an InsideThing"
}
}
oo::class create Container {
constructor {} {
puts "Created a [self] that is a Container"
InsideThing create inner1
InsideThing create inner2
}
destructor {
puts "Deleted a [self] that is a Container"
}
}
set c [Container new]
puts "Do stuff..."
$c destroy
如果运行该代码,则会得到以下结果:
Created a ::oo::Obj13 that is a Container
Made a ::oo::Obj13::inner1 that is an InsideThing
Made a ::oo::Obj13::inner2 that is an InsideThing
Do stuff...
Deleted a ::oo::Obj13 that is a Container
Deleted a ::oo::Obj13::inner1 that is an InsideThing
Deleted a ::oo::Obj13::inner2 that is an InsideThing
创建了一个容器::oo::Obj13
制作了一个::oo::Obj13::inner1,它是一个InsideThing
制作了一个::oo::Obj13::inner2,它是一个InsideThing
做些事情。。。
删除了作为容器的a::oo::Obj13
删除了作为InsideThing的a::oo::Obj13::inner1
删除了作为InsideThing的a::oo::Obj13::inner2
这种技术在TDBC中广泛用于在结果集和语句的容器(分别是语句和连接)上下文中管理结果集和语句
Tk Megawidgets
最后,如果您使用TclOO创建Tk MegaWidget,您肯定会使用
create
,但会以重写形式,因为Tk Widget必须具有以
开头的非限定名称,并且具有特定的具体层次结构,强烈建议MegaWidget遵循相同的模式。因为名称在这种情况下非常重要,new
是错误的方法;最好从创建开始。Tk 8.6有一些支持类(未公开描述,但内部用于某些对话框),使这类事情变得更容易:Tk::Megawidget
和Tk::MegawidgetClass
。有关详细信息,请查看Tk 8.6发行版。谢谢Donal。真的很有帮助,从创造者那里得到解释也很有趣。