Extending Class Families
A common convention in MooTools is to have numerous classes that break out functionality. This allows you to build upon the functionality of classes through extension and also keep your code base small when you don’t need everything and the kitchen sink. Consequently we get Fx, Fx.Css, Fx.Tween, Fx.Morph, etc.
What happens when you want to extend numerous classes with the same functionality? For instance, I have a popup manager called StickyWin. One of my scripts is called StickyWin.Ajax.js, which adds Ajax functionality to all the popup classes, creating *.Ajax classes (so, for instance, StickyWin.Fx is extended to StickyWin.Fx.Ajax).
Consider this code:
var Foo = new Class({
apple: 'red'
});
var Bar = new Class({
lemon: 'yellow'
});
//If we want to extend Foo with the exact same
//functionality and create Foo.Talker, then we must
//repeat ourselves:
Foo.Talker = new Class({
Extends: Foo,
speak: function(prop){
alert(prop + 's are ' + this[prop]);
//apples are red
}
});
Bar.Talker = new Class({
Extends: Bar,
speak: function(prop){
alert(prop + 's are ' + this[prop]);
//lemons are yellow
}
});
Whenever you are writing code if you find yourself repeating yourself there’s almost always a way to avoid it. The solution here is to create a method that extends classes for us with the new functionality.
(function(){ //put it in a closer so we don't pollute the global namespace
var makeTalker = function(classToExtend){
return new Class({
Extends: classToExtend,
speak: function(prop){
alert(prop + 's are ' + this[prop]);
//apples are red
}
});
};
Bar.Talker = makeTalker(Bar);
Foo.Talker = makeTalker(Foo);
})();
Now we’ve created both sub-classes but only written our code in one place.
Not To Be Confused with Class.Implement
The above solution is useful for creating subclasses. This shouldn’t be confused with Implementing functionality into existing classes. In the above example, we created Foo.Talker and Bar.Talker, which do not change Bar or Foo at all.
We could, instead, just add our methods directly to those classes with Class.Implement. This works well when you want to overwrite existing methods or add new ones, but remember that Class.Implement doesn’t let you reference this.parent, so you can’t add functionality to existing methods, only overwrite them. More details on Implement vs Extend in the MooTorial.
Follow @clientcide on twitter to get notified of new posts.
To follow me personally on twitter, follow @anutron.
January 6th, 2009 at 3:34 pm
Just a note. In the first code example, line 14 is supposed to be ‘Extends: Foo’.
January 6th, 2009 at 3:45 pm
Nice catch. Thanks.