Page 1 of 1

Making Abstract classes in JavaScript

Posted: Fri Oct 13, 2006 7:45 am
by Chris Corbyn
Since JavaScript doesn't support interfaces (does NS support them actually? I noticed it's a reserved word in NS!) does anybody have a better approach than this?

Code: Select all

function MyAbstractClass()
{
    this.someCommonMethod = function() {} //These would implement some actual functionality
    this.someOtherMethod = function() {}

    this.someAsbtractMethod = function()
    {
        throw new Error('MyAbstractClass.someAbstractMethod must be overridden by child');
    }
}

function MyClassUsingTheInterfaceOfTheAbstractClass()
{
    this.performOperationOnObject = function(obj)
    {
        //Cheap and dirty type checking
        if (!(obj instanceof MyAbstractClass))
        {
            throw new Error('MyClassUsingTheInterfaceOfTheAbstractClass.performOperationOnObject requires parameter 1 to be object of type MyAbstractClass');
        }
        obj.someCommonMethod();
        obj.someOtherMethod();
        obj.someAbstractMethod();
    }
}

function MyOverridingClass()
{
     this.someAbstractMethod = function() {}
}
MyOverridingClass.prototype = new MyAbstractClass;

var myObject = new MyClassUsingTheInterfaceOfTheAbstractClass();
myObject.performOperationOnObject(new MyOverridingClass());

Posted: Fri Oct 13, 2006 11:00 am
by Luke
In Javascript: The Definitive Guide, 5th Edition, this is how they created an abstract class...

Code: Select all

function Classy() {}
Classy.prototype.method = function (arg) {
    throw "Classy.method() is abstract. You must override it!"
}
Looks like you're on the right track :wink:

Posted: Fri Oct 13, 2006 2:48 pm
by Chris Corbyn
Ha! Well there you have it :) Thanks for the reference. My reading around JavaScript topics is a bit left to be desired. I've started developing in JavaScript the way I would with OOP in PHP; even following similar design patterns. I wonder if anybody has started a design patterns for JavaScript website :idea:

Posted: Sat Oct 14, 2006 1:35 am
by Weirdan
btw, it's generally believed that duck typing is preferred in js, as opposed to many other languages.

Posted: Sat Oct 14, 2006 4:25 am
by Chris Corbyn
Weirdan wrote:btw, it's generally believed that duck typing is preferred in js, as opposed to many other languages.
Never heard that term before? I'll have a google around. For now (shock, horror!) I'm off out to make a start on my xmas shopping 8O

Posted: Sat Oct 14, 2006 5:05 am
by n00b Saibot
d11wtq wrote:
Weirdan wrote:btw, it's generally believed that duck typing is preferred in js, as opposed to many other languages.
Never heard that term before?
me too :?
d11wtq wrote:For now (shock, horror!) I'm off out to make a start on my xmas shopping 8O
8O from now?

Posted: Sat Oct 14, 2006 10:52 am
by Chris Corbyn
n00b Saibot wrote:8O from now?
Gotta start these things early to spread the cost :) As it turns out though, I spent £70 on a winter jumper and a beanie hat for myself and not a penny on anybody else... talk about being selfish :P

Posted: Sat Oct 14, 2006 8:42 pm
by Luke
Duck Typing: "If it walks like a duck and quacks like a duck, it's a duck!"
So to translate to Javascript: "If it implements all the methods defined by a class, it is an instance of that class!"

So basically, since Javascript is so loosely typed, if an object implements all the properties defined by a class, it may be treated just like said class, regardless of whether it was created with said class's constructor.

This is all in the book I mentioned before... You really should pick up a copy, I've never seen such a complete documentation of javascript. It's $33 at Amazon... I apologize, I'm not quite sure what that translates to in the UK. :oops:

Some code example from the book:

Code: Select all

function borrows(o, c){
	
	// This should be obvious...
	if(o instanceof c) return true;
	
	// Can't test whether built-in types borrow methods because their methods aren't enumerable... :(
	if(c == Array || c == Boolean || c == Date || c == Error || c == Function || c == Number || c == RegExp || c == String) return false;
	
	if(typeof o == "function") o = o.prototype;
	var proto = c.prototype;
	for(var p in proto){
		// Ignore properties that are not functions
		if(typeof proto[p] != "function") continue;
		if(o[p] != proto[p]) return false;
	}
	return true;
	
}