Crear un método común a todas las instancias de MovieClip (AS2)
Muy sencillo, direis: créalo en el prototipo de movieclip. Pero, ¿qué sucede cuando estamos escribiendo AS 2.0?
Ahora no podemos modificar la clase MovieClip, sino que sólo podemos extenderla, y añadir nuevos métodos a esas clases hijas. ¿Seguro?. Veamos:
La teoría sobre programación orientada a objetos es que si queremos añadir algún método a la clase movieclip, lo que debemos hacer es:
class net.designnation.exp.Mezcla extends MovieClip{
function Mezcla(){
trace("constructor de mezcla");
}
//Este es el método que queremos que
// tengan todos los movieclips
private function metodoAS1(){
trace("este es el método particular");
}
}
Bien, esto nos permite hacer que la clase Mezcla tenga todos los métodos heredados de MovieClip, y además el método metodoAS1. Pero ese método AS1 pertenece a la clase Mezcla, y sólo a ella. Es decir, que si creáramos otra clase que extendiera de movieclip, si queremos que tenga el método metodoAS1, deberíamos definirle.
De todas formas, algunos ya habreis pensado: distintas clases con el mismo método.... ¿interfaces?. Efectivamente, podemos implementar un interface:
interface net.designnation.exp.MCInterface{
public function metodoAS1():Void;
}
Y hacer que nuestras clases lo implementen:
import net.designnation.exp.*;
class net.designnation.exp.Mezcla extends MovieClip
implements MCInterface{
function Mezcla(){
trace("constructor de mezcla");
}
//Este es el método que forma parte del interfaz.
//debemos definirlo aquí!!!
private function metodoAS1(){
trace("éste es el método particular");
}
}
¿Está nuestro problema solucionado?. No del todo. El hacer que una clase implemente un interfaz sólo sirve para que el compilador nos dé un error si esa clase no tiene implementados todos los métodos del interfaz. Dicho de otra manera, el hacer que una clas implemente un interfaz, nos sirve sólo para asegurarnos que esa clase implementa una serie de métodos, que hemos enumerado en otro lugar (el interfaz).
Pero esos métodos debemos implementarlos en todas y cada una de las clases que implementen el interfaz, con lo que tampoco conseguimos lo que queremos, que por si alguien se ha perdido (y yo estoy a punto) no es más que definir una sola vez un método, y que ese método sea accesible a MovieClip y a todas sus subclases.
Probablemente la solución más estricta y elegante sería hacer una clase que heredara de movieclip, con el método que queremos implementar definido en ella, y hacer que el resto de clases hereden de esa clase, en vez de hacerlas heredar de movieclip.
Pero si por algo nos caracterizamos los programadores (o desarrolladores, o scripters o lo que seamos) que trabajamos con actionscript es por que no nos gustan demasiado las soluciones estrictas y elegantes. Para eso ya hay gente que sabe muchísimo Java.
Por lo tanto, vamos a lo que nos gusta de verdad.
Recordemos la “vieja” forma de definir un método común a todas las instancias de una clase:
MovieClip.prototype.metodoAS1 = function(){
trace("Bien!. Se ha ejecutado el método AS1");
};
Si escribimos ese código en el primer frame de nuestro fla, antes de cualquier otra cosa, todas las instancias de MovieClip tendrán implementado ese método.
¿Pero qué pasa con nuestra clase?. Veamos: nuestra clase hereda de MovieClip, luego:
class net.designnation.exp.Mezcla extends MovieClip{
function Mezcla(){
trace("constructor de la clase Mezcla");
}
private function metodoAS2(){
trace("Y yo soy el método AS2");
};
public function onRollOver(){
//Ejecuto el método metodoAS1 de la superclase.
super.metodoAS1();
metodoAS2();
};
}
Para ilustrar el ejemplo, vamos a crear un movieclip, que utilizaremos como botón. Dentro de ese clip, hay que dibujar una forma cualquiera, porque lo que queremos es asignarle a la clase anterior, y ver qué pasa cuando hacemos rollOver sobre él.
Una vez creado el movieclip, en sus propiedades de vinculación, asignamos como Indentificador “MiClip” y como Clase de AS 2.0 “net.designnation.exp.Mezcla”
Por tanto, el código del primer frame de nuestro fla queda de la siguiente manera:
MovieClip.prototype.metodoAS1 = function(){
trace("Bien!. Se ha ejecutado el método AS1");
};
//Al hacer attachmovie, se instanciará la clase Mezcla
this.attachMovie("MiClip", "instancia", 1);
¿Qué pasa al hacer rollover sobre el clip?. Premio!. Se ejecuta el método que definimos en el prototype de MovieClip. Pero, ese método reside en la superclase de la clase Mezcla, luego ¿cómo podemos ejecutar desde ese método otros métodos de la clase Mezcla?
Modifiquemos un poco los métodos metodoAS2 y onRollOver de Mezcla
private function metodoAS2(arg){
trace("Y yo soy el método AS2 " + arg);
};
public function onRollOver(){
super.metodoAS1(this);
};
También la definición de metodoAS1 en el prototype de MovieClip:
MovieClip.prototype.metodoAS1 = function(ref){
trace("Bien!. Método AS1" + this.constante);
ref.metodoAS2("x " + this._width);
};
¿Qué hemos hecho?. Pues desde la clase Mezcla llamamos al método de su superclase, pasándole una referencia a la clase desde la que dicho método ha sido llamado. Por tanto, ahora, la superclase sabe qué clase la ha llamado, y puede saber a quién debe contestar.
¿A alguien le han quedado ganas de hacer algún comentario?
Comentarios
Hola ;-). Bonita explicación. Mi aportación es que no hace falta poner super porque la clase Mezcla buscará primero su propia clase si esta el metodoAS1 de no se así sigue la cadena (es decir de quién hereda) y lo busca allí. Como su clase madre es MovieClip y el prototypo si que dispone de esa función la ejecuta. El code
class subClass extends MovieClip{
var metodoAS1:Function;
function subClass(){
trace("consrtuct");
}
function onRollOver(){
metodoAS1(this);
}
}
Saludos
Publicado por: fazeaction | Enero 15, 2004 03:37 PM
Efectivamente, también puede resolverse como has comentado, fazeaction, siempre y cuando, como has escrito en tu código, se defina (aunque no se implemente) dicho método en la definición de la clase, para evitar errores de compilación.
En tu caso, es la línea
var metodoAS1:Function;
Gracias por tu aportación.
Publicado por: Cesar Tardaguila | Enero 16, 2004 08:35 AM
hola
Publicado por: Juan Pablo | Agosto 10, 2004 10:06 PM