Newsgroups: comp.lang.smalltalk
Path: cantaloupe.srv.cs.cmu.edu!rochester!cornellcs!newsstand.cit.cornell.edu!portc01.blue.aol.com!newsxfer2.itd.umich.edu!howland.erols.net!news.mathworks.com!uunet!in3.uu.net!news2.new-york.net!not-for-mail
From: vlad@world2u.com (Vlastimil Adamovsky)
Subject: Re: beginner: Multiple Constructors - the Smalltalk way?
X-Newsreader: Forte Free Agent 1.0.82
X-Nntp-Posting-User: (Unauthenticated)
Message-ID: <DyF973.IvI@news2.new-york.net>
References: <324bf3d2.270082@news.iac.net>
X-Trace: 843878989/24403
X-Nntp-Posting-Host: i123.116.world2u.com
Date: Sat, 28 Sep 1996 02:49:43 GMT
Lines: 94

bmulert@iac.net (Bill Mulert) wrote:

>I'm looking for the proper Smalltalk way to mimic the multiple
>constructors that C++ and Java employ. For example, a class may have
>multiple constructors, each with a differing signature. 

>A Smalltalk Class can have one each of "new" and "new:", but
>I'd like my Class to instantiate itself by either:
>    no argument
>    an Integer argument
>    a Stream argument
>    possibly other single argument types

>Is there a standard way of having a Class return a new instance of
>itself, allowing for a number of unique constructor signatures,
>without resorting to unique methods names for each
>constructor/signature?

I remember I had had a simmilar (maybe the same) problem.

Here are two (2)  solutions I used to use when I was younger:

the problem code:
 
  |myVeryInnovativeCollection|

    myVeryInnovativeCollection := #( aString aNumber aRectangle    
    aButton) collect:[:each|  GraphicElement createFrom: each].


To make it work see 

solution #1:
 I defined an instance methods for String, Number, Rectangle and Button classes.

The name of the method was #createInstanceOfClass: aClass. The aClass was in my
examle a GraphicElement. 

** instance method for String *****
createInstanceOfClass: aClass

^ aClass createFromString: self


**instance  method for Number***
createInstanceOfClass: aClass

^ aClass createFromNumber: self


etc....

Of course you need to define class methods in GraphicElement class
#createFromString:,createFromNumber: etc, which will do the dirty job.

solution #2:

** class method for GraphicElement ********************************
createFrom: anObject

^self perform: ('createFrom', anObject class name,':') asSymbol with: anObject
**************************************************************************************************

Of course you need to define class methods in GraphicElement class
#createFromString:,createFromNumber: etc, which will do the dirty job.


solution #3:
** class method for GraphicElement ********************************
createFrom: anObject

 |dict|

 dict := IdentityDictionary new.
 dict at: String put: [:a| .....someCode using the a argument]; 
       at: Rectangle put: [:a| .....someCode using the a argument and

		               returning an instance of the GraphicElement ]; 
       at: Number put: [:a| .....someCode using the a argument....]; 
      at: Button put: [:a| .....someCode using the a argument.....].

^ (dict at: anObject class ifAbsent:[[:a| self new]]) value: anObject

**************************************************************************************************

solution #4

etc.......



 Vlastimil Adamovsky
 ** C++ and Smalltalk consultant**

