[英]How to specify class for instance variable in smalltalk
可能我對小話的概念還不夠了解,但這是我的問題:
我正在創建一個類,我們將其稱為Main-class ,它具有一個實例變量bar ,我想成為某個類-Other-class ,並在Main-class方法中使用該Other-class '方法有點像這樣:
Object subclass: #Other-class
instanceVariableNames: 'foo'
classVariableNames: ''
poolDictionaries: ''
category: 'Custom-class'
setFoo: newFoo
foo := newFoo.
和主班 :
Object subclass: #Main-class
instanceVariableNames: 'bar'
classVariableNames: ''
poolDictionaries: ''
category: 'Custom-class'
newBar: val
bar := Bar new.
bar setFoo: val.
顯然,我收到一個沒有setFoo方法的錯誤。 但是,如何指定我希望bar成為特定類的變量,然后在其上使用該類的方法呢?
關於問題的標題:您沒有。 Smalltalk是一種動態類型化的語言,這意味着變量的值在不同的時間點可以具有不同的類型-不會為變量聲明類型。 但是對於人類來說,您可以在類注釋中記錄變量的實際類型(請參閱系統瀏覽器中實例側和類側按鈕旁邊的?按鈕)。
關於您的問題:您必須確保分配給實例變量bar
的對象具有適當的類型。 在這種情況下,它必須了解消息setFoo:
在第二個代碼段中,這意味着:
Bar
您應該使用另一個可以響應setFoo:
Other-class
,例如Other-class
(由於連字符,這是一個奇怪的名稱,您不能輕易地在方法中引用它,而使用CamelCase),填寫變量,或 setFoo:
必須為Bar
類實現。 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對象具有很多哲學上的相似之處。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.