让我们假设我们有两个类如下:
oo::class create InsideThing {
constructor {} {
puts "Made a [self] that is an InsideThing"
}
destructor {
puts "Deleted a [self] that is an InsideThing"
}
method echo {text} {
puts "[self]: $text"
}
}
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"
}
method echo1 {text} {
# how to do something like this:
$inner1 echo $text
}
}
我将如何访问这些内部对象?我想做类似以下的事情:
set c [Container new]
# (1) accessing inner1 indirectly
$c echo1 "Hallo World"
# (2) accessing inner1 dirctly
$c inner1 echo "Hallo World"
有办法吗?这种接近甚至有意义吗?
我想要实现的是一个嵌套的对象结构(基本上是树状的)。我希望能够通过调用节点上的方法(例如父,子)来导航这个结构。同时销毁root也应该销毁所有孩子(这就是为什么我使用create
在父命名空间内创建嵌套对象的方法)
答案 0 :(得分:3)
要简单地使用包含的对象,只需使用它的 local 名称,您应该知道它,因为您在构造函数中create
了它。它不需要保存在变量中;确保它是一个唯一的名称是完全无足轻重的,因为它将位于一个唯一的命名空间(实例命名空间;每个TclOO对象都有自己的私有命名空间用于此类事情)并且您可以完全控制它。
使用转发方法最容易暴露内部对象。
TclOO提供了两种主要的用户可配置方法:“普通”proc
- 类似于method
声明的方法,以及您声明的转发方法(有点像interp alias
)与forward
。您转发的内容是针对实例名称空间解决的,该名称空间是 ultra -useful!
特别是,您可以在容器类上创建一个转发到相关内部对象的forward
方法。像这样(InsideThing
没有变化):
oo::class create Container {
constructor {} {
puts "Created a [self] that is a Container"
InsideThing create innerABC
InsideThing create innerDEF
}
destructor {
puts "Deleted a [self] that is a Container"
}
method echo1 {text} {
# Just use the name. That's all.
innerABC echo $text
}
forward inner1 innerABC
forward inner2 innerDEF
}
然后你可以调用内部对象,如:
$c inner1 echo "Yo!"
或者您可以使用这样的中间正常方法:
$c echo1 "Hiya!"
由你决定。 (转发版本在我的非正式测试中使用修改后的代码版本快速提高了大约20%,并且实现了无关紧要的echo
方法。然而,实际代码会注意到差异显着减少;微基准测试很少有用实际上。)