smalltalk公共初始化

| 有什么方法可以“隐藏”初始化方法,以便构造后无法调用它? 我想要类似的东西:
Class>>new: params
  ^super newInstance initializedBy: [
    \"actual initialization code\"
]
    
已邀请:
您可以执行以下操作:
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约定很简单...外部的任何人都不应在初始化方法类别中调用任何东西,而不能真正了解他们为什么这样做。 您也可以将所有内容保留在类中:
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.
    
听起来像是我的依赖项注入框架Seuss的工作,它为您提供了对初始化过程的大量控制(默认情况下,将初始化AFTER构造参数的调用传递到setter中)。不过,它仍未发布。 要回答您的问题,无需使用Seuss,您可以覆盖new,这样它就不会调用
initialize:
MyClass>>new
   ^ self basicNew
    
IIUC您正在询问是否可以将方法设为私有。答案是是,不是:) Smalltalk中的约定是将\“ private \”方法放在\“ private \”类别中。这是向外部用户发出的信号,表明它不会被使用,但是没有任何东西可以阻止他们实际使用它。实际上,这似乎很好。 那是你在问什么吗?如果没有,更多的细节将有所帮助。     
您也不能实现#initialize,无论您想放置在哪里,但又不想从#new调用,您都可以将其放入另一个具有其他名称的方法中。     
我可以想到几种实现最终目标的方法, a)添加\'initialized \'实例变量,并在设置为true时跳过#initialize,
   Contact>>initialize  
     initialized == true ifTrue: [^self].  
     enabled := false.  
     lastModified := Timestamp now.  
     initialized := true.
b)添加一个测试用例,该用例通过您的代码运行重写搜索,并计算不在其自身类层次结构的#new方法中的#initialize发送者。实际上,如果您自己的类是从一个通用模型继承的,则您实际上应该只有一个#initialize发送者,并且可以在测试用例中轻松断言。 希望这可以帮助。     
实例方法:
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)图像中尝试过-可以! 当然,可以将辅助方法放在层次结构中的较高位置。     

要回复问题请先登录注册