smalltalk public initialize

时间:2011-04-25 15:38:02

标签: smalltalk squeak pharo

有没有办法“隐藏”初始化方法,以便在构建后无法调用它?

我想要像:

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

6 个答案:

答案 0 :(得分:1)

你可以这样做:

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.

答案 1 :(得分:0)

听起来像是我的依赖注入框架Seuss的工作,它可以让你对初始化过程进行大量控制(默认情况下,调用初始化后将构造参数传递给setter)。不过,它还没有发布。

要在不使用Seuss的情况下回答您的问题,您可以覆盖新的,以便它不会调用initialize:

MyClass>>new
   ^ self basicNew

答案 2 :(得分:0)

IIUC你问的是否可以将方法设为私有。答案是肯定的,没有:) Smalltalk中的惯例是将“私有”方法放在“私有”类别中。这是向外部用户发出的一个信号,即它不会被使用,但是没有任何东西阻止他们实际使用它。在实践中,这似乎工作正常。

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

答案 3 :(得分:0)

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

答案 4 :(得分:0)

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

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

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

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

希望这有帮助。

答案 5 :(得分: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)图像中尝试过它 - 有效! 当然,帮助方法可以放在层次结构中更高的位置......