簡體   English   中英

在Pharo或Smalltalk中制作構造函數

[英]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指的是類,因為該方法在類的一側。 但由於personPerson的實例, age: anAge必須在實例端定義消息name: aNameage: 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM