Herencia múltiple

JSimpleClass soporta la herencia múltiple, podemos heredar métodos y atributos de más de un clase, mediante el método público $$implement.
Hay que destacar que heredaremos todos los métodos y propiedades públicos, excepto los estáticos y reservados de JSimpleClass ($$constructor,$$super, etc...).


var ClassA = Class.create("ClassA",function(){
      var value = "value A";
	  this.A = "A";
	  this.getValue = function(){
		 return value;
	  };
});

var ClassB = Class.create("ClassB",function(){
      var value = "value B";
	  this.B = "B";
	  this.getValue = function(){
		 return value;
	  };
});

var ClassM = Class.create("ClassM",function(){
	this.$$implement(ClassA,ClassB);
	var value = "value M";
	this.M = "M";
	this.getValue = function(){
	 return value;
	};
	this.$$constructor = function(){};
 });


var instM = new ClassM();
alert(instM.A + " " + instM.B + " " + instM.M + " " + instM.getValue())
// A B M value M


Es importante llamar al método $$implement antes de declarar cualquier atributo o método público, ya que si por ejemplo, llamamos a $$implement al final de la clase, sobrescribiremos los métodos y propiedades públicos declaradas en la clase.

En el ejemplo anterior tenemos tres métodos comunes getValue, si quisiéramos añadir el método de la ClassB, sólo tenemos que eliminar el método getValue de ClassM, pero si queremos el método de ClassA, tenemos dos posibilidades, cambiar el orden de los argumentos, this.$$implement(ClassB,ClassA), La otra posibilidad podemos verla en el siguiente ejemplo:


var ClassA = Class.create("ClassA",function(){
      var value = "value A";
	  this.A = "A";
	  this.getValue = function(){
		 return value;
	  };
});

var ClassB = Class.create("ClassB",function(){
      var value = "value B";
	  this.B = "B";
	  this.getValue = function(){
		 return value;
	  };
});

var ClassM = Class.create("ClassM",function(){
	this.$$implement(ClassA);
	this.$$implement(ClassB,["getValue"]);
	this.M = "M";
	this.$$constructor = function(){};
 });


var instM = new ClassM();
alert(instM.A + " " + instM.B + " " + instM.M + " " + instM.getValue())
// A B M value A
alert(instM.$$implemented );// ClassA, ClassB
alert(Class.getImplementedClasses(ClassM));// ClassA, ClassB

Con $$implement tenemos la opción mediante un array de decir que propiedades no queremos añadir, habrás podido observar la importancia del orden a la hora de sobrescribir los métodos y atributos.

El método getImplementedClasses o el atributo $$implement de la instancia, nos devuelve un array con el nombre de las clases implementadas.
También es posible añadir propiedad de un objeto JavaScript, para que getImplementedClasses o $$implement registre el nombre del objeto, el objeto tiene que tener la propiedad $$className.


var ObjectA = {
	$$className:"ObjectA",
	getValue:function(){
		return "A";
	}
}; 

var ClassM = Class.create("ClassM",function(){
	this.$$implement(ObjectA);
	this.M = "M";
	this.$$constructor = function(){};
 });


var instM = new ClassM();
alert(instM.getValue());//  value:objectA
alert(instM.$$implemented );// ObjectA
alert(Class.getImplementedClasses(ClassM));// ,ObjectA

Por ultimo es posible añadir métodos y propiedades fuera del cuerpo de la clase, con implement.


var ObjectA = {
	$$className:"ObjectA",
	getValue:function(){
		return "A";
	}
}; 

var ClassM = Class.create("ClassM",function(){
	this.$$implement(ObjectA);
	this.M = "M";
	this.$$constructor = function(){};
 });

ClassM.implement({
	getValue:function(){
		return "Z";
	},
	X:"X"
});
var ClassN = Class.extend("ClassN",ClassM,function(){
	this.$$constructor = function(){};
});

ClassN.implement({
	X:"N"
});

var instN = new ClassN();
alert(instN.X + " " + instN.getValue());//  N A
alert(instN.$$implemented );// ObjectA
alert(Class.getImplementedClasses(ClassN));// ObjectA

Los métodos y atributos añadidos mediante implement no pueden sobrescribir a los declarados dentro de la clase y a su vez pueden ser sobrescritos.