我想在Pharo中实现一个小类,所以我做了这个:
Object subclass: #Person
instanceVariableNames: 'name age'
classVariableNames: ''
category: 'Test'
我想模拟一个构造函数,所以我做了一个像下面这样的方法:
newName:aName newAge:aAge
"comment stating purpose of message"
name:=aName.
age:=aAge.
^self.
但是当我想像这样从法罗的操场上打电话时:
objPerson:=Person newName:'Carl' newAge: 10.
法罗不承认,我做错了什么?
表达式 Person newName: 'Carl' newAge: 10
是给类对象Person
的消息。因此,您必须在Person
的类端实现它。
你的代码需要像这样调整
Person class >> newName: aName newAge: anAge
| person |
person := self new.
person name: aName.
person age: anAge.
^person
请注意,在上面的代码中,self
引用类,因为该方法位于类端。但是由于person
是Person
的实例,消息name: aName
和age: anAge
必须在实例端定义。
因此,在实例端,您需要添加两个资源库:
Person >> name: aString
name := aString
Person >> age: anInteger
age := anInteger
使用这三种方法,您应该能够运行您的示例。
关于编码风格的一些附加评论:
首先,我会为"构造函数"方法选择一个不同的选择器(在 Smalltalk 中,我们称这些为"实例创建"方法)。例如
Person class >> named: aString age: anInteger
^self new name: aString; age: anInteger
其次,不需要对新创建的实例使用临时person
,因为表达式self new
已经引用了这样的实例。
最后,请注意在
^self new name: aString; age: anInteger
这意味着消息age: anInteger
将被发送到name: aString
的同一接收方,在这种情况下恰好是self new
返回的新实例。
尽管总的来说我同意 Leandro 的回答,但它将访问器暴露在私有属性中。
Kent Beck在他的Smalltalk最佳实践模式(我强烈推荐)中建议使用set
作为实例端构造函数的前缀,例如:
"add to class side to 'instance creation' protocol"
Person>>class name: aName age: anAge
^ self new
setName: aName age: anAge;
yourself
"add to instance side to 'initialization' protocol"
Person>>setName: aName age: anAge
name := aName.
age := anAge.
这样,您可以控制是否公开属性。
或者你可以坚持你原来的名字,只添加new
,你忘记了。
objPerson := Person new newName:'Carl' newAge: 10.