About KCP and automatic initialize
Avi Bryant
avi at beta4.com
Fri Sep 12 02:55:32 UTC 2003
On Thursday, September 11, 2003, at 05:57 PM, Julian Fitzell wrote:
> If I remove the call to "super initialize" from #initializeWithClass:
> then it still doesn't work because then #initialize (and therefore
> #beExclusive) is called before I've added my sub filters. The only
> way to make it work as I desire is to use #basicNew in my #forClass:
> method, which I'm led to believe is not considered the right way to do
> such things.
The only formal conventions I know of for dealing with this problem
actually come not from Smalltalk but from the NeXT FoundationKit for
Objective-C.
There is some description of these conventions in the documentation of
#init and #new on NSObject:
http://developer.apple.com/documentation/Cocoa/Reference/Foundation/
ObjC_classic/Classes/NSObject.html#//apple_ref/doc/uid/20000050/init
http://developer.apple.com/documentation/Cocoa/Reference/Foundation/
ObjC_classic/Classes/NSObject.html#//apple_ref/doc/uid/20000050/new
I'll try to summarize, translated into Smalltalk terms:
- Object provides a blank #initialize method. This, like all
initialization methods, may be overriden.
- Every class has exactly one "designated initializer" method. If a
class has more than one initialization methods, the designated
initializer is the most general or the most canonical - usually the one
with the most arguments. For example, for a Point the designated
initializer might be this:
initializeWithX: xNumber y: yNumber
super initialize.
x := xNumber.
y := yNumber.
- The designated initializer must call its superclass' designated
initializer. Here, because Point is a subclass of Object, and
#initialize is the designated initializer for Object,
Point>>initializeWithX:y: must call Object>>initialize.
- All other initializers must call the designated initializer. For
example, you might (for some reason) have an initializer that just took
an X value:
initializeWithX: aNumber
self initializeWithX: aNumber y: 0.
They do *not* call any super methods.
- The above rule also applies to any inherited designated
initialization methods - they have to be rewritten in terms of the new
designated initializer. So, you would have to add an #initialize
method:
initialize
self initializeWithX: 0 y: 0
- Any initializer, designated or not, may have a corresponding class
side method. For example, Object provides Object class>>new which
corresponds to #initialize.
new
^ self basicNew initialize
These class side methods always call #basicNew and their intialization
method. They do not get overriden. Point might provide:
x: xNumber y: yNumber
^ self basicNew initializeWithX: xNumber y: yNumber
x: aNumber
^ self basicNew initializeWithX: aNumber
Note that the inherited #new will call the overridden
Point>>initialize, which will provide the default 0 at 0 values, so
there's no way to get an inconsistent instance (without directly using
#basicNew).
So, the short answer to Julian's question is: yes, use #basicNew in
#forClass:. If you make sure to follow the rest of these conventions,
the problems that people have with #basicNew (in terms of missing
superclass initialization) should not come up.
More information about the Squeak-dev
mailing list
|