[英]making a constructor in Pharo or 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.
但是當我想在Pharo的操場上打電話時,就像這樣:
objPerson:=Person newName:'Carl' newAge: 10.
Pharo不承認它,我做錯了什么?
表達式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
的實例, age: anAge
必須在實例端定義消息name: aName
和age: anAge
。
因此,在實例端,您需要添加兩個setter:
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.
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.