在 Pharo 或 Smalltalk 中制作构造函数



我想在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引用类,因为该方法位于类端。但是由于personPerson的实例,消息name: aNameage: 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.

相关内容

  • 没有找到相关文章

最新更新