有没有办法“隐藏”初始化方法,以便在构建后无法调用它?
我想要像:
Class>>new: params
^super newInstance initializedBy: [
"actual initialization code"
]
答案 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)图像中尝试过它 - 有效! 当然,帮助方法可以放在层次结构中更高的位置......