tcl - TclOO : 从另一个类获取基础对象
问题描述
我有 2 个类fruit
,orange
我的目标是获得允许我构建类的对象fruit
。
namespace eval test {}
oo::class create test::fruit {
constructor {type} {
if {$type eq "orange"} {
set orange [test::orange new]
}
}
destructor {
puts "[self] destroy..."
}
}
oo::class create test::orange {
constructor {} {
}
destructor {
puts "[self] destroy..."
}
}
set f [test::fruit new "orange"]
我找到了一个解决方案,from class ::test::fruit
通过将我的orange
变量保存在一个全局变量中来找到基础对象(),baseobject
如下所示:
oo::class create test::fruit {
variable baseobject
constructor {type} {
if {$type eq "orange"} {
set orange [test::orange new]
set baseobject $orange
}
}
method baseclass {} {
return $baseobject
}
}
有什么命令,另一种解决方案吗?我不知道我的方式是否是面向对象的......
解决方案
我不是 100% 确定你想在这里做什么。您可以使用info object
andinfo class
获取 TclOO 系统知道的所有关系;他们从为整个系统提供动力的底层 C 结构中读取信息。
尤其:
info class instances Foo
获取类的实例Foo
。info class subclasses Foo
获取类的(直接)子类Foo
。info class superclasses Foo
获取 class 的(直接)超类Foo
。::oo::object
如果您没有另外说,这将是;所有类都将其作为最终的超类。info object class bar
获取对象的类bar
。
oo::class create Foo
oo::class create Foo2 {superclass Foo}
Foo create bar
puts [info class instances Foo]; # => ::bar
puts [info class subclasses Foo]; # => ::Foo2
puts [info class superclasses Foo]; # => ::oo::object
puts [info object class bar]; # => ::Foo
如果对象和类之间的关系不是标准关系之一,您必须自己捕捉它;有几种方法,您已经知道其中一种简单的方法,即以某种方式将名称保存在实例变量中。
还要记住,所有类本身都是其元类的实例,称为oo::class
(或其子类之一)。这意味着您可以使用info object class Foo
来获取创建的类Foo
。是的,这意味着它oo::class
本身就是一个实例;它的构造(以及 的构造oo::object
)是特殊的。
如果你想安排一个对象被另一个对象拥有,即在所有者对象被销毁时自动销毁,最简单的方法是让拥有对象的名称在所有者的实例命名空间中(create
方法oo::object
在解析你给它的名字的意思时是命名空间感知的),然后它会在所有者离开时自动销毁,不需要显式销毁。
method makeMyOrange args {
test::orange create myOrange {*}$args
}
如果您只有一组固定的拥有对象,那么在您的实例命名空间中为它们提供您喜欢的名称是微不足道的。否则,用于生成名称的简单实例本地计数器也很简单:
method makeOneOfMyOranges args {
variable counter
test::orange create myOrange[incr counter] {*}$args
}
请注意,该new
方法oo::object
使名称不是以这种方式拥有的。(或者更确切地说,它生成的名称归 TclOO 本身所有。)
如果您希望其他一些随机的其他不相关的对象知道是谁制作了它,请将其[self]
作为参数传递给构造函数。
oo::class create test::orange {
constructor {maker} {
puts "I was made by $maker"
}
}
oo::class create test::fruit {
constructor {} {
set orange [test::orange new [self]]
}
}
推荐阅读
- indexeddb - dexie.js:第一次嵌套查询很慢
- mysql - MYSQL的USING子句
- javascript - 在本机反应中将批量照片上传到 Firebase 存储
- c++ - 在 BST heap-use-after-free 错误中删除节点
- angular - 将自定义控件添加到角度选择下拉控件
- sql - SQL Server 中对用户定义的函数有什么需求?
- model-view-controller - 选择 DropDownListFor 时,我可以回发更多值(例如 ViewBag 或 Viewmodel 值)吗?
- kotlin - 如何修复“未解决的参考。由于接收器类型不匹配,以下候选均不适用”
- html - 如何将模态表单连接到mysql数据库?
- javascript - 给定node.js中的日期集合,如何获取每天的最新时间?