overridding without subclassing examples

Ron Teitelbaum Ron at USMedRec.com
Wed Sep 19 12:55:13 UTC 2007


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