繁体   English   中英

如何在Smalltalk中为实例变量指定类

[英]How to specify class for instance variable in smalltalk

可能我对小话的概念还不够了解,但这是我的问题:

我正在创建一个类,我们将其称为Main-class ,它具有一个实例变量bar ,我想成为某个类-Other-class ,并在Main-class方法中使用该Other-class '方法有点像这样:

    Object subclass: #Other-class
        instanceVariableNames: 'foo'
        classVariableNames: ''
        poolDictionaries: ''
        category: 'Custom-class'

setFoo: newFoo

    foo := newFoo.

主班

  Object subclass: #Main-class
        instanceVariableNames: 'bar'
        classVariableNames: ''
        poolDictionaries: ''
        category: 'Custom-class'

newBar: val

    bar := Bar new. 
    bar setFoo: val.

显然,我收到一个没有setFoo方法的错误。 但是,如何指定我希望bar成为特定类的变量,然后在其上使用该类的方法呢?

关于问题的标题:您没有。 Smalltalk是一种动态类型化的语言,这意味着变量的值在不同的时间点可以具有不同的类型-不会为变量声明类型。 但是对于人类来说,您可以在类注释中记录变量的实际类型(请参阅系统浏览器中实例侧和类侧按钮旁边的?按钮)。

关于您的问题:您必须确保分配给实例变量bar的对象具有适当的类型。 在这种情况下,它必须了解消息setFoo: 在第二个代码段中,这意味着:

  1. 而不是Bar您应该使用另一个可以响应setFoo: Other-class ,例如Other-class (由于连字符,这是一个奇怪的名称,您不能轻易地在方法中引用它,而使用CamelCase),填写变量,或
  2. setFoo:必须为Bar类实现。

respondsTo:方法可用于确定对象是否响应消息:

bar respondsTo: #setFoo
  ifTrue: [bar setFoo: val]
  ifFalse: [missiles launch]

如果您不希望在bar不了解setFoo时发射导弹,请决定要发生什么。 也许您的程序应该因错误而崩溃。 这并不比发射导弹来得极端,但仍然是一种极端,很少真正需要的,尤其是在其他人正在使用您的软件的情况下。

选项:仅使用正确类型的对象

ifFalse: [bar := ClassWithSetFoo new; setFoo: val]

选项:通过修改对象的类来扩展对象以执行所需的操作

ifFalse: [ (bar class) addInstVarName: 'foo'.
           (bar class) compile: 'setFoo: newFoo [foo := newFoo]'.
           bar setFoo: val. ]

根据上下文,第二个选项可能是也可能不是您想要执行的操作。 即使不是,它也说明了Smalltalk动态键入的强大功能。 Ruby on Rails的很多“魔术”都是使用类似的策略构建的。 这是可能的,因为Ruby对象与Smalltalk对象具有很多哲学上的相似之处。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM