Tutorials, extensions, and source files for ActionScript, Flash, and other Adobe products.

 

senocular.com ActionScript Library

multipleInheritance.as

Name: Multiple Inheritance (kind of) additionalSuper();
Author: senocular: www.senocular.com
Date: 1899-12-31T00:01:17.900
Documentation:
Constructor Class Function additionalSuper():
- Allows a type of multiple inheritance for a Flash class.
Additional super classes are kept within an array in the 
Class called _supers which can be manupulated at will.  When
an instance of said class attempts to call a method not
within its own prototype (or instance) the supers added with
this function are searched, and if found, the method of that
super is run for the instance - more or less inheritance ;)

Class.additionalSuper(superClass [, constructorArgumentsArray]);

Arguments:
- superClass: an additional superclass the current class is to 'inherit' from.
- constructorArgumentsArray: (optional) an array of arguments for the superClass
constructor.  If this argument is passed, the constructor of the passed superclass will
be run for the current class's prototype object adding properties or doing whatever is
set in that constructor.  If you want the constructor to run but it takes no arguments
just pass something like true or [] otherwise it wont be called.  Default: nothing,
superclass constructor not called.

Returns:
- nothing.

Example:
 ClassA = function(){} // super 1
ClassA.prototype.methodA = function(){
	trace("Class A method for " + this._name);
}
ClassB = function(){} // super 2
ClassB.prototype.methodB = function(){
	trace("Class B method for " + this._name);
}
ClassC = function(value){ // super 3
	this.value = value	
}
ClassC.prototype.methodC = function(){
	trace("Class C method for " + this._name);
}


ClassX = function(name){// subclass
	this._name = name;
}
ClassX.prototype = new ClassA(); // normal inherit from A
ClassX.additionalSuper(ClassB); // set up class B
ClassX.additionalSuper(ClassC, ["passedValue"]); // set up class C

instance = new ClassX("bob");
instance.methodA(); // traces "Class A method for bob"
instance.methodB(); // traces "Class B method for bob"
instance.methodC(); // traces "Class C method for bob"
trace(instance.value); // traces "passedValue" (assigned in prototype from C constructor)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
Function.prototype.additionalSuper = function(superClass, args){
	if (!this._supers) this._supers = [];
	var len = this._supers.length;
	this._supers[len] = superClass;
	if (args != undefined) superClass.apply(this.prototype, args);
	if (!this.prototype.__resolve){
		class = this;
		this.prototype.__resolve = function(p){
			for (var i=0; i<class._supers.length; i++){
				if (class._supers[i].prototype[p]) return class._supers[i].prototype[p];
			}
		}
		ASSetPropFlags(this.prototype, "__resolve", 1);
	}
	return len;
}
Object.prototype.supers = function(){
	if (!this.__constructor__) return undefined;
	if (!arguments.length){
		var L = this.__constructor__._supers.length;
		for (var i=0; i<L; i++)	this.__constructor__._supers[i].call(this);
	}else{
		var args, sup, L = arguments.length;
		for (var i=0; i<L; ++i){
			args = (arguments[i+1] instanceof Array) ? arguments[i+1] : undefined;
			if (arguments[i] instanceof Function){
				arguments[i].apply(this, args);
			}else this.__constructor__._supers[arguments[i]].apply(this, args);
			if (args) ++i;
		}
	}
}
Object.prototype.superMethod = function(sup, meth, args){
	if (!this.__constructor__) return undefined;
	if (sup instanceof Function) return sup.prototype[meth].apply(this, args);
	else return this.__constructor__._supers[sup].prototype[meth].apply(this, args);
}
ASSetPropFlags(Function.prototype, "additionalSuper", 1);
ASSetPropFlags(Object.prototype, "supers,superMethod", 1);