Override (Sobrescribir métodos y atributos).

Al heredar los métodos y atributos públicos de la superclase, es posible sobrescribir estos y tener acceso a los métodos y atributos sobrescritos de la superclase, para poder acceder a estos utilizaremos la palabra reservada $$super.


function ClassA(){
	var message = "ClassA";
	this.getMessage = function(){
		return message;
	};
	this.setMessage = function(msg){
		message = msg;
	};
	// constructor de la clase
	this.$$constructor = function(msg){
		 message =  msg || message;
	};

};

var ClassA = Class.create("ClassA",ClassA);

function ClassB(){
	var message = "ClassB";
	this.sender = "anonymous";
	this.getMessage = function(){
		return this.sender + " says "  + message  + " " +  this.$$super[0].getMessage();
	};
	this.setMessage = function(msg){
		message = msg;
	};
	// constructor de la clase
	this.$$constructor = function(nm,msg){
		 message =  msg || message;
		 this.sender = nm;
	};
}

var ClassB = Class.extend("ClassB",ClassA,ClassB);

var peter = new ClassB("Peter", " hello");
alert(peter.getMessage()) // "Peter says hello ClassA"

Como puedes ver $$super es un array, para tener acceso a ClaseA desde ClaseB hemos puesto 0 en el índice de $$super, ya que ClaseA es la clase superior en la jerarquía. Si tenemos una jerarquía de clases mayor y queremos saber en que nivel esta una clase tenemos el método getIndex del objecto Class.


 Class.getIndex(ClassA); return 0
 Class.getIndex(ClassB); return 1

Una cosa que tenemos que tener en cuenta cuando sobrescribimos un método es si este método utiliza alguna atributo privado.


function ClassA(){
	
	var value = "default A";
	
	this.getValue = function(){
		return value + " ["+ this.$$className + "]";
	};
	this.setValue = function(v){
		value = v
	};
	this.$$constructor = function(v){
		this.setValue(v || value);
	};

};

var classA = Class.create("ClassA",ClassA);

function ClassB(){

	var value = "default B";
	
	this.setValue = function(v){
		value = v
	};	
	
	this.$$constructor = function(v){
		this.setValue(v || value);
	};
};

var ClassB = Class.extend("ClassB",ClassA,ClassB);

var instB = new ClassB("instance B");
alert(instB.getValue());// default A[ClassB]


Como puedes ver instB.getValue devuelve el valor value de ClassA, esto se debe a que los métodos públicos sólo tienen acceso a los atributos y métodos privados de la clase donde fueron declarados.
Lo que deberemos hacer es sobrescribir el método getValue.


function ClassA(){
	
	var value = "default A";
	
	this.getValue = function(){
		return value + " ["+ this.$$className + "]";
	};
	this.setValue = function(v){
		value = v
	};
	this.$$constructor = function(v){
		this.setValue(v || value);
	};

};

var classA = Class.create("ClassA",ClassA);

function ClassB(){

	var value = "default B";
	
	this.getValue = function(){
		return value + " ["+ this.$$className + "]";
	};	
	
	this.setValue = function(v){
		value = v
	};	
	
	this.$$constructor = function(v){
		this.setValue(v || value);
	};
};

var ClassB = Class.extend("ClassB",ClassA,ClassB);

var instB = new ClassB("instance B");
alert(instB.getValue());//instance B [ClassB]

Para obtener una clase determinada dentro de una jerarquía podemos hacerlo directamente o mediante $$super.


var ClassA = Class.create("ClassA",function(){
	this.getFirstClass = function(){
		return Class.getName(ClassA);
	};
	this.$$constructor = function(){
	};
});

var ClassB = Class.extend("ClassB",ClassA,function(){
	this.$$constructor = function(){
	};
});

var ClassC = Class.extend("ClassB",ClassB,function(){
	this.$$constructor = function(){
	};
});

var iA = new ClassA();
var iB = new ClassB();
var iC = new ClassC();

alert(iA.getFirstClass() + "\n" + iB.getFirstClass() + "\n" + iC.getFirstClass());
/*
ClassA
ClassA
ClassA
*/

JSimpleClass permite clonar clases, si clonásemos ClassA, el método getFirtClass devolverá "ClassA" tanto en la clase clonada como en la original.
Con $$super no tenemos este problema.


var ClassA = Class.create("ClassA",function(){
	this.getFirstClass = function(){
		// si $$super existe es que estamos el nivel 1 de la jerarquía
		if(this.$$super) return Class.getName(this.$$super[0].$$class);
		else return Class.getName(this.$$class);
	};
	this.$$constructor = function(){
	};
});

var CloneClassA = Class.clone("CloneClassA",ClassA);
var ClassB = Class.extend("ClassB",ClassA,function(){
	this.$$constructor = function(){
	};
});

var ClassC = Class.extend("ClassB",ClassB,function(){
	this.$$constructor = function(){
	};
});

var iA = new ClassA();
var iB = new ClassB();
var iC = new ClassC();
var cA = new CloneClassA();

alert(iA.getFirstClass() + "\n" + iB.getFirstClass() + "\n" + iC.getFirstClass() + "\n" +  cA.getFirstClass());
/*
ClassA
ClassA
ClassA
CloneClassA 
*/

Para saber si estamos en la primera clase de la jerarquía, nos servimos de $$super, ya que este atributo no existe en ésta, también podemos utilizar Class.getIndex.


var ClassA = Class.create("ClassA",function(){

	this.$$constructor = function(){
	};
});

var ClassB = Class.extend("ClassB",ClassA,function(){
	this.getSecondClass = function(){
	
		return Class.getIndex(this) == 1 ? this.$$className: this.$$super[1].$$className;
	};
	this.$$constructor = function(){
	};
});

var ClassC = Class.extend("ClassB",ClassB,function(){
	this.$$constructor = function(){
	};
});


var iB = new ClassB();
var iC = new ClassC();

alert(iB.getSecondClass() + "\n" + iC.getSecondClass());
/*
ClassB
ClassB
*/

Como puedes ver $$super nos proporciona un gran control.