2

有什么方法可以“隐藏”初始化方法,使其在构造后无法调用?

我想要类似的东西:

Class>>new: params
  ^super newInstance initializedBy: [
    "actual initialization code"
]
4

6 回答 6

2

你可以这样做:

Class>>initializeInstance: anInstance
  anInstance instVarNamed: #i put: 1.
  anInstance instVarNamed: #j put: 2.

但是,你仍然有一个初始化方法,但现在它在类方面,并没有真正做你想要的。但是..您可以尝试:

Class>>new: params
  ^super newInstance initializedBy: [ anInstance |
    anInstance instVarNamed: #i put: 1.
    anInstance someMethodCalledOnInitalization.
]

在实例方面:

initializedBy: anInitializationBlock

  anInitializationBlock value: self.

我认为这可以大致了解您想要什么。我认为它不值得付出努力,因为我可以使用 instVarNamed 并更改您的对象。smalltalk 约定很简单……外部人员不应调用初始化方法类别中的任何内容,而无需真正了解他们为什么这样做。

你也可以把它全部放在你的课堂上 w:

Class>>new: params
  anInstance := super newInstance.
  ^ self initialize: anInstance using: [ anInstance |
      anInstance instVarNamed: #j put: 1.
  ].

Class>>initialize: anInstance using: aBlock
  aBlock value: anInstance.
  ^ anInstance.
于 2011-04-27T11:25:58.403 回答
0

听起来像是 Seuss 的工作,我的依赖注入框架,它使您可以对初始化过程进行大量控制(默认情况下,调用初始化 AFTER 构造参数传递到设置器)。不过,它仍然未发布。

要回答您的问题,不使用 Seuss,您可以覆盖 new,这样它就不会调用initialize:

MyClass>>new
   ^ self basicNew
于 2011-04-25T16:23:02.507 回答
0

IIUC 您问是否可以将方法设为私有。答案是肯定的和否定的 :) Smalltalk 中的约定是将“私有”方法放在“私有”类别中。这是向外部用户发出的一个信号,表明它不会被使用,但无论如何都没有阻止他们实际使用它。在实践中,这似乎工作正常。

那是你问的吗?如果没有,更多细节会有所帮助。

于 2011-04-25T16:29:53.623 回答
0

你也可以不实现#initialize 和任何你想放在那里但不是从#new 调用的东西,你把它放在另一个名称的另一个方法中。

于 2011-04-25T16:51:59.783 回答
0

我可以想到几种不同的方法来实现最终目标,

a) 添加 'initialized' 实例变量并在设置为 true 时跳过 #initialize,

   Contact>>initialize  
     initialized == true ifTrue: [^self].  
     enabled := false.  
     lastModified := Timestamp now.  
     initialized := true.

b) 添加一个测试用例,通过您的代码运行重写搜索,并计算不在其自己的类层次结构的#new 方法中的#initialize 发件人。事实上,如果您自己的类继承自一个通用模型,那么您实际上应该只有一个#initialize 发送者,并且可以在测试用例中轻松断言。

希望这可以帮助。

于 2011-04-26T12:20:56.100 回答
0

实例方法:

initialize
    ... do what you need to do ...
    ... then ...
    self blockInitialize

blockInitialize
    self changeClassTo:(self class subclassWithoutInitialize)

类方法:

isSubclassWithoutInitialize
    ^ false

subclassWithoutInitialize
    ^ self subclasses 
        detect:[:cls | cls isSubclassWithoutInitialize]
        ifNone:[
            newClass := self 
                subclass:(self name,'WithoutInitialize')
                instanceVariableNames:''
                classVariableNames:''
                category:'*hidden*'.
            newClass class compile:'isSubclassWithoutInitialize ^ true].
            newClass compile:'initialize ^ self].
            newClass.
        ].

在我的 (ST/X) 图像中尝试过 - 有效!当然,辅助方法可以放在层次结构的更高层......

于 2011-05-10T22:03:51.560 回答