overridding without subclassing examples

Brad Fuller bradallenfuller at yahoo.com
Wed Sep 19 14:53:02 UTC 2007


Thanks, Ron. I've read and heard about this, but to me it looks dangerous and 
would seem to incur overhead so I always avoided entertaining the idea. But, 
it's interesting. ALWAYS nice to have an example and I thank you for the 
extended example. Very helpful!

On Wed September 19 2007, Ron Teitelbaum wrote:
> Hi Brad,
>
> I realize you have moved on but there are two more I thought I'd mention.
>
> You could wrap your class if you do not want to change it.  Simply create a
> wrapper class, then change does not understand to pass messages that you
> didn't override to the class.  Then you can override your class all you
> want by simply implementing the messages you want to override on the
> wrapper class.
>
> So for example:
>
> Object subclass: #Radio
>
> Radio class >> bands
> 	"return the receiving bands that this class handles"
> 	^#('FM' 'AM')
>
> Object subclass: #RadioWrapper
> 	instanceVariableNames: 'subject'
>
> RadioWrapper class >> doesNotUnderstand: aMessage
> 	"Handle messages that are not implemented on this wrapper by passing
> them to #subject"
> 	^self subject class perform: aMessage.
>
> RadioWrapper >> doesNotUnderstand: aMessage
> 	"Handle messages that are not implemented on this wrapper by passing
> them to #subject"
> 	^self subject perform: aMessage.
>
> Now you can override
>
> RadioWrapper class >> bands
> 	"override the base method to add 'HD'"
> 	^self subject bands copyWith: 'HD'.
>
> To use your new class you need to wrap your class
>
> RadioWrapper class >> wrap: aRadio
> 	"wrap the radio class for overrides"
> 	^self new
> 		subject: aRadio;
> 		yourself
>
> now in your code you need to change instances of Radio to use your new
> wrapped class.
>
> aRadio := Radio new.
>
> Becomes
>
> aRadio := RadioWrapper wrap: Radio new.
>
> So in your example you could just wrap morphs with a wrapper that changes
> what you need changed.  What's nice about this pattern is that you can wrap
> multiple levels and they will continue to work, passing down methods that
> it doesn't understand and handling those that it does.  In other words a
> wrapper can also be wrapped with a different wrapper and it will still
> work.
>
> The down side to this is that every message send that is not implemented on
> your wrapped class has additional overhead so this is not recommended if
> performance is a concern.  The overhead is minimal and usually not a
> problem.
>
> The second method if you have an instvar that needs to be changed is to
> break encapsulation completely by using instVarAt: to set the value
> directly.  This is really not a good idea and can cause a lot of problems
> that are difficult to diagnose.  (Don't tell anyone I recommend this :)  )
>
> Hope that helps,
>
> Ron Teitelbaum
>
> > -----Original Message-----
> > From: Brad Fuller
> >
> > On Tue September 18 2007, Brad Fuller wrote:
> > > Is there a way to override an instance method w/o subclassing?
> > > For instance, class Morph has a method that returns true, but I want
> > > the that method to return false when instancing some types of Morphs
> > > and
> >
> > others
> >
> > > not. (there is no setter/getter for this method.) Is there a way to do
> >
> > that
> >
> > > w/o adding a setter/getter to Morph or subclassing the different
> > > Morphs?
> >
> > Thanks everyone, I think I have to go on for now.





More information about the Squeak-dev mailing list