TclOO:从另一个类获取基对象

TclOO:从另一个类获取基对象,tcl,Tcl,我有两个类fruit和orange,我的目标是获得允许我构建fruit类的对象 namespace eval test {} oo::class create test::fruit { constructor {type} { if {$type eq "orange"} { set orange [test::orange new] } } destructor {

我有两个类
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"]
通过将我的
orange
变量保存在全局变量
baseobject
中,我找到了一个查找基本对象的解决方案(
from class::test::fruit
),如下所示:

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对象
info类
获取TCOO系统知道的所有关系;他们从底层C结构中读取信息,这些结构为整个系统提供动力

特别是:

  • info类实例Foo
    获取类的实例
    Foo
  • info class subclasses Foo
    获取类
    Foo
    的(直接)子类
  • info类超类Foo
    获取类
    Foo
    的(直接)超类。这将是
    ::oo::object
    ,如果您没有另外说过;所有类都将其作为最终超类
  • info object class bar
    获取对象的类
    bar
如果对象和类之间的关系不是标准关系之一,那么您必须自己捕获它;有几种方法,您已经知道其中一种简单的方法,即以某种方式将名称保存在实例变量中

还要记住,所有类本身都是元类的实例,元类称为
oo::class
(或其子类之一)。这意味着您可以使用
info object class Foo
获取创建
Foo
的类。是的,这意味着
oo::class
是自身的一个实例;它的结构(以及
oo::object
)是特殊的


如果您想安排一个对象归另一个对象所有,即在销毁所有者对象时自动销毁,最简单的方法是将所拥有对象的名称置于所有者的实例命名空间中(当解析所给名称的含义时,
oo::object
create
方法可以识别名称空间),然后当所有者离开时,它将自动销毁,无需显式销毁

method makeMyOrange args {
    test::orange create myOrange {*}$args
}
如果您只有一组固定的已拥有对象,则在实例命名空间中为它们指定您喜欢的名称是微不足道的。否则,用于生成名称的简单实例本地计数器也是微不足道的:

method makeOneOfMyOranges args {
    variable counter
    test::orange create myOrange[incr counter] {*}$args
}
请注意,
oo::object
new
方法生成的名称不是以这种方式拥有的(或者更确切地说,它生成的名称是由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]]
    }
}

谢谢,这是我的第二个问题?如果我销毁我的对象
::test::fruit
::test::orange
将自动销毁?我将详细查看您的答案最后…为了简单起见,我由另一个创建了一个类…两者之间有关系吗?我一直在阅读您的答案。。。
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]]
    }
}