簡體   English   中英

如何在Smalltalk中為實例變量指定類

[英]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: 在第二個代碼段中,這意味着:

  1. 而不是Bar您應該使用另一個可以響應setFoo: Other-class ,例如Other-class (由於連字符,這是一個奇怪的名稱,您不能輕易地在方法中引用它,而使用CamelCase),填寫變量,或
  2. 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.

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