可能我还没有理解smalltalk的概念,但这是我的问题:
我正在创建一个类,我们称之为 Main-class ,它有一个实例变量 bar ,我想成为某个类 - 其他类,并在 Main-class 方法中使用此 Other-class '方法,如下所示:
Object subclass: #Other-class
instanceVariableNames: 'foo'
classVariableNames: ''
poolDictionaries: ''
category: 'Custom-class'
setFoo: newFoo
foo := newFoo.
Main-class :
Object subclass: #Main-class
instanceVariableNames: 'bar'
classVariableNames: ''
poolDictionaries: ''
category: 'Custom-class'
newBar: val
bar := Bar new.
bar setFoo: val.
显然,我收到一条错误,即没有 setFoo 方法。 但是,如何指定我希望 bar 是特定类的变量,然后在其上使用该类的方法?
答案 0 :(得分:4)
关于问题的标题:你没有。 Smalltalk是一种动态类型语言,这意味着变量的值在不同的时间点可以有不同的类型 - 不为变量声明类型。但对于人类,您可以在类注释中注意变量的实际类型(请参阅系统浏览器中实例端和类侧按钮旁边的?按钮)。
关于您的问题:您必须确保分配给实例变量bar
的对象是合适的类型。在这种情况下,它必须理解消息setFoo:
。在您的第二个代码段中,这意味着:
Bar
的类,而不是setFoo:
,例如Other-class
(由于连字符,这是一个奇怪的名字,你不能轻易在你的方法中引用,改为使用CamelCase,填充变量,或setFoo:
实施Bar
。答案 1 :(得分:0)
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的对象有很多哲学相似之处。