Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!uunet!seismo!rutgers!sri-spam!parcvax!susser From: susser@parcvax.Xerox.COM (Josh Susser) Newsgroups: comp.lang.smalltalk Subject: Re: A question... Message-ID: <409@parcvax.Xerox.COM> Date: Wed, 5-Aug-87 16:34:13 EDT Article-I.D.: parcvax.409 Posted: Wed Aug 5 16:34:13 1987 Date-Received: Sat, 8-Aug-87 06:04:14 EDT References: <4357@felix.UUCP> Reply-To: susser@parcvax.xerox.com.UUCP (Josh Susser) Organization: Xerox Special Information Systems, Pasadena, CA Lines: 82 Keywords: multiple polymorphism In article <4357@felix.UUCP> preston@felix.UUCP (Preston Bannister) writes: > >I have been writing a set of class definitions to support graphics in >Little Smalltalk from the descriptions in the Smalltalk-80 books. > >The class Point responds to '+'. The examples show both: > aPoint + aPoint i.e. (1 @ 2) + (3 @ 4) = (4 @ 6) >and > aPoint + aNumber i.e. (1 @ 2) + 3 = (4 @ 5) > >What I don't see is how to write the method for '+' without explicitly >testing the class of the parameter. Something like: > > + delta > (delta class == Point) > ifTrue: [^ Point new x: (self x + (delta x)) y: (self y + (delta y)) ] > ifFalse: [^ Point new x: (self x + delta) y: (self y + delta) ] > >Somehow I would have expected to write two methods: > + aPoint > ^ Point new x: (self x + (delta x)) y: (self y + (delta y)) > + aNumber > ^ Point new x: (self x + delta) y: (self y + delta) >But this doesn't seem possible. > >Am I missing something?? > >======================================== >Preston L. Bannister >USENET : ucbvax!trwrb!felix!preston >BIX : plb >CompuServe : 71350,3505 >GEnie : p.bannister Your instincts are right - explicitly testing the class of an object is an evil thing to do. Besides, what if you want to add a subclass of Point? Or something that just behaves like a Point? There are two good ways to handle a situation like this. They both involve writing more than one method. The first way, you make sure that the argument is a Point, by coercing it if necessary. Like so: Integer: asPoint ^self@self Point: asPoint ^self + delta delta <- delta asPoint. ^(x + delta x)@(y + delta y) The other way is using a technique known as multiple polymorhism: Integer: plusPoint: aPoint ^(self + aPoint x)@(self + aPoint y) Point: plusPoint: aPoint ^(x + aPoint x)@(y + aPoint y) + delta ^delta plusPoint: self Both of these techniques are nicer than explicitly testing the class of the argument. The advantage here is that you can then add anything to a Point as long as is understands "asPoint" or "plusPoint:". Who really cares what class an object is as long as it behaves correctly anyway? --Josh Susser susser.pasa@xerox.com susser@parcvax.xerox.com When the going gets tough, it takes a brave man to lay back and party.