Comunidad de diseño web y desarrollo en internet online

Duda básica: Parametros hacia constructor en clase externa

Citar            
MensajeEscrito el 25 Mar 2010 12:23 pm
Buenas a tod@s.

Antes de exponer mi duda quisiera aclarar que hace poco tiempo que uso Flash/AS3 y menos tiempo aún que "programo" usando OPP con lo cual puede que mi duda sea una autentica parida.

Devido a esto que comento, estoy en una fase de mi curva de aprendizaje en la que aun trabajo en el fotograma 1 de mi fla e importo todo lo necesario desde biblioteca y clases externas de modo que la mayoría de ellas contienen funcionalidades básicas como botones y otras cosillas no muy complejas. En mi intento de profundizar en el tema un poco más me estan surgiendo algunas dudas.

He llegado a un punto en el que me he estancado con las clases ya que no entiendo muy bien la manera en la que mi fla se comunica con los constructores de mis clases ya que si, por ejemplo, en una función contenida en mi linea de tiempo puedo pasarle parametros con los que trabajar de esta manera:

Código ActionScript :

var myNum:Number = 3;
traceNum(myNum);
function traceNum(n:Number):void{
   trace(n);
}


No consigo entender porque cuando creo una clase externa que en principio debiera hacer exactamente lo mismo, como por ejemplo:

Código ActionScript :

package
{
   import flash.display.MovieClip
   
   public class Test extends MovieClip
   {
      private var myNum:Number;
      
      public function Test(n:Number):void;
      {
         myNum=n;
         trace(myNum);
      }
   }
}


y esto otro en mi fla

Código ActionScript :

var myNum:Number = 3;


var myTest:Test = new Test(myNum);


Obtengo errores que me dicen que no he definido mi variabe myNum en mi clase. No funcionan los constructores de igual forma que las funciones? porque no me acepta el valor que le mando desde mi fla?.

Perdón si la duda es de perogrullo o algo relacionado con aspectos teóricos fundamentales de AS3. Como he comentado hace muy poco que he empezado a usar Flash/AS3 y el 75% de lo que se lo he aprendido de manera autodidacta.

Gracias de antemano.

Un saludo.

tsk.

Por teskostudio

34 de clabLevel



 

firefox
Citar            
MensajeEscrito el 25 Mar 2010 12:36 pm
Te sobra un ";" en la definición del Constructor

Código ActionScript :

public function Test(n:Number):void //<--aquí tenías un ";"
{
....
}

Por Eliseo2

710 de clabLevel



 

firefox
Citar            
MensajeEscrito el 25 Mar 2010 01:15 pm
Dios mio... la puta manía de poner el punto y coma por todos lados.

Gracias Eliseo2.

Por teskostudio

34 de clabLevel



 

firefox
Citar            
MensajeEscrito el 25 Mar 2010 04:06 pm
Bueno.

Poco me ha durado la alegría. Esto del ActionScript me hace sentir imbécil a veces...

Veamos. Sería este proceso que acabamos de aclarar, distinto si en lugar de crear una clase no asociada a ningun MovieClip como en mi ejemplo inicial, asocio esa clase a algun objeto de mi biblioteca?. Digamos que tengo esto en mi clase:

Código ActionScript :

package tsk.utils{
   
   import flash.display.MovieClip   
   
   public class ThumbObj extends MovieClip {
      
      public function ThumbObj(u:String) {
         trace(u);
      }
   }
}


Y en mi fla tengo un MovieClip en mi biblioteca linkado con nombre de clase thumb y como clase base tsk.utils.ThumbObj. Tal que así:

Código ActionScript :

var myUrl:String = "blablahblah";

var myThumb:thumb = new thumb(myUrl);


Porque me lanza el error 1136: Incorrect number of arguments. Expected 0.?. No le estoy pasando ese valor al constructor tal y como lo hacíamos en el ejemplo anterior?.

No lo pillo.

Por teskostudio

34 de clabLevel



 

firefox
Citar            
MensajeEscrito el 27 Mar 2010 12:14 pm
Tesko, cuando ienes un símbolo con un nombre de clase y NO tenemos un .as, Flash trata de generar la clase. Esta Clase la genera, sin ningún argumento. Así que tienes que tener un
thumb.as con un código como

Código ActionScript :

package{
   import flash.display.MovieClip
   public class thumb extends ThumbObj{
     public function thumb(u:String=null){
        super(u);
     }
  }
}

NOTA:Cuando leí lo que querías hacer me dió la impresión de que lo que querías tener es un Símbolo cuya clase base es flash.display.MovieClip y como clase ThumbObj
NOTA2:La Clase MovieClip es la única Clase de Flash, junto con Object, que es "not sealled". Esto es, que le podemos añadir propiedades usando la notación de punto. Vamos, con sólo escribir

Código ActionScript :

var mc:MovieClip=new MovieClip()
mc.nueva_propiedad="valor";

Por Eliseo2

710 de clabLevel



 

msie8
Citar            
MensajeEscrito el 28 Mar 2010 02:19 am
Eo.

Gracias por la respuesta Eliseo2, este tipo de notas que me dejas me sirven y mucho.

Al respecto de lo que comentas en tu nota1, he puesto como clase base de mi objeto de biblioteca la clase ThumbObject porque ésta, extiende la clase MovieCLip, de esta forma puedo en un futuro crear otros objetos dentro de este mismo fla que referencien la misma clase base sólo cambiando la clase básica al exportar para actionscript. Creo. Es posible eso no?. No tengo claro si es otra de esas cosas que no tengo claras en su base teórica.

Otra duda que me surge leyendo tu mensaje es: si primero creo mi .as y luego dentro de mi fla creo mi ThumbObject y lo linko, sucedería lo mismo que comentas?, es decir, debería usar en mi clase externa la expresión super para acceder a mi fla?. O esto sucede sólo si primero creo el objeto y trato de linkarlo a una clase inexistente?.

Por otra parte, si no uso MovieClip como clase base de mi símbolo sigo pudiendo acceder a las propiedades de mi ThumbObject mediante la sintaxis de punto?.

Gracias de nuevo por tu tiempo.

Salu2.

tsk.

Por teskostudio

34 de clabLevel



 

firefox
Citar            
MensajeEscrito el 28 Mar 2010 09:09 am
Por partes.
Sí. Cada símbolo ha de pertenecer a una clase distinta. Luego si queremos que un conjunto de símbolos se comporten de un modo parecido, los suyo, tal y como dices, es que tngan la misma clase base. Se me ocurre como ejemplo el "típico" juego de las "moscas" en las que unas naves se mueven y te disparan, que las naves son diferentes de aspecto, pero todas se mueven igual. Si definimos el comportamiento en la clase Enemigo, y les ponemos a todas las naves esa clase base se moverán y sólo se diferencian en el aspecto (otra cosa es que sea más eficiente controlarlas desde un único ENTER_FRAME desde la película principal)
No. La instrucción super lo que hace es llamar al constructor de la clase desde la que se hereda (de la que se extiende). No tiene nada que ver con la película principal. Si extendemos una clase de un S`prite o de un MovieClip, p.e. No necesitamos llamar al constructor de la clase de la que se extiende, puesto que no hacemos mucho más en el constructor. En tu ejemplo de la clase Test que extendía de TestObject sí que hacemos "algo" (asignar el valor del parámetro a una variable). Por eso llamo a "super()".
Me expliqué mal. Por una parte, en Flash sólo hay dos clases "no selladas". MovieClip y Object. Cualquier clase que extienda de una de ellas podemos añadirles propiedades sin declararlas. Así podemos escribir

Código ActionScript :

var mc:MovieClip=new MovieClip()
mc.variable="Hola mundo"

Pero no podemos escribir

Código ActionScript :

var sp:Sprite=new Sprite()
sp.varible="Hola Mundo" //<---da error

Eso es todo a lo que me refería con clase selladas y no selladas.

Cuando definimos una clase, podemos definir, dentro de dicha clase una variable. Esta la podemos declarar como pública o como privada. si la declaramos como pública se podrá acceder a ella con la notación de punto. si la declaramos como privada, sólo podremos acceder a ella con la notación de punto si hacemos unas funciones getter/setter

Código ActionScript :

public class Test{
    //declaración de variables
    public var variable_publica:Number
    private var _variable_privada:Number
    //constructor
    public function Test(){
    }
    //funciones getter/setter para acceder a _variable_privada
    public function set variable_privada(u:Number):Void {
            _variable_privada=u
    }
    public function get variable_privada():Number{
            return _variable_privada
    }
    public function metodo1(){
         trace(variable_publica+":"+_variable_privada
    }
}

Vemos que las funciones getter/setter son unos "métodos" especiales en los que no tenemos que poner los paréntesis y que normalmente sirven para dar valor o recoger el valor de unas variables (posiblemente comprobando si son valores correctos)

Código ActionScript :

var test:Test=new Test()
test.variable_publica=4
test.variable_privada=5
test.metodo()
trace(test.variable_publica)
trace(test.variable_privada)

puff, menuda "chapa"

Por Eliseo2

710 de clabLevel



 

msie8
Citar            
MensajeEscrito el 28 Mar 2010 05:00 pm
Jaja si lo de chapa lo dices por tu explicación te aseguro que no es así. Cuanto más voy aprendiendo de AS más me gusta y ejemplos como los que me dejas me sirven para entenderlo mejor.

Recapitulando y haciendo referencia a este codigo:

Código ActionScript :

package{ 
   import flash.display.MovieClip 
   public class thumb extends ThumbObj{ 
     public function thumb(u:String=null){ 
        super(u); 
     } 
  } 
} 


En un principio no lo vi bien y de ahí que te preguntase si creando primero la clase y luego el símbolo asociado era necesario usar la expresión super() para acceder al String que pasamos desde el fla ya que entendí que estabas trabajando sobre ThumbObj. Perdón, no lo vi bien, ahora me doy cuenta que lo que haces es extender la clase ThumbObj creando esta nueva clase thumb que irá asociada a mi objeto de biblioteca y por eso necesitas de super(). Hasta ahí lo veo todo claro. Lo que no acabo de entender es la relación existente entre clase y subclase (ThumbObj y thumb). Pongamos como ejemplo que tengo el siguiente código en mi fla, donde project es el tag de mi XML que controla la duración del loop y Content es un Sprite donde voy agragando los diferentes thumb:

Código ActionScript :

for (var i:Number = 0; i < xmlData.project.length(); i++){
      var myThumb:thumb = new thumb("la url de una imagen");
      thumb.x = 562*i
      addChild(myThumb);
      Content.addChild(myThumb);      
   }


Entiendo que como comentas he de tener un thumb.as que haga de clase a mi símbolo thumb pero no acabo de ver como podemos aceptar el String desde thumb hacía ThumbObj tal y como están estructuradas las clases hasta ahora ya que si entendí bien tus ejemplos el String se lo acabo pasando a ThumbObj para que esta clase base se encargue del procesamiento de la información de thumb. Sin embargo tal y como tengo ahora mismo ThumbObj, que es así:


Código ActionScript :

package tsk.utils{
   
   import flash.display.MovieClip   
   
   public class ThumbObj extends MovieClip {
      
      public var myString:String;
      
      public function ThumbObj(s:String) {
         myString=u;
         trace(myString);
      }
   }
}


Teniendo para thumb el código de más arriba, si pruebo la película de esta forma me tira el error 1136: Incorrect number of arguments. Expected 0. poniendome como fuente del error el código de mi fla donde instancio la variable e intento pasar el String al constructor de thumb. Como puedo hacer para que ThumbObj me acepte el String que viene de thumb que a su vez viene del fla?.

Perdona si soy muy reiterativo con mi pregunta pero no lo acabo de entender.

tsk.

Por teskostudio

34 de clabLevel



 

firefox
Citar            
MensajeEscrito el 29 Mar 2010 02:17 pm
La idea de extender una clase es para "que haga algo más". Los códigos que hemos puesto, hacen lo mismo la Clase Thumb que la Clase ThumbObject, así que NO es necesario tener DOS clases distintas.

Cuando extendemos una clase de otra es "como si" escribiéramos TODO el código de una, DENTRO de la otra. Así que no es que "le esté pasando el valor". Simplemente no tenemos que escribir todo el código desde el principio

Normalmente tendríamos una clase Thumb que extienda de thumbObject si, p.e. los objetos de la Clase Thumb se pueden draguear y los otros no. Si no, no tendríamos por qué hacer dos clases.

Otro ejemplo es que quieres asociar un símbolo a una clase, y tienes, p.e. Thumb1 y Thumb2 (que extienden ambos de ThumbObject), uno con un marco cuadrado alrededor y otro con un marco circular. Ya que van a hacer todo igual, pero tienen esa pequeña diferencia, podemos elegir hacer uno u otro.

Sí, se pueden hacer clases que no estén asociadas a ningún símbolo. ¡ojo! siempre que quieras asociar una clase a un símbolo, si quieres que tu clase tenga argumentos y que haya algún que otro objeto de esa clase en el stage has de poner los parámetros por defecto.

Vale, respecto al error de incorrecto número de argumentos, no tengo aquí el Flash -lo estoy haciendo desde FlasDevelop, pero no debería-

Por Eliseo2

710 de clabLevel



 

firefox
Citar            
MensajeEscrito el 31 Mar 2010 12:38 am
Eo!.

Gracias de nuevo por los tips y la ayuda Eliseo2.

Al final conseguí hacer lo que quería, o sea asociar un símbolo de mi biblioteca a una clase pasando de mi fla. a esa clase una serie de valores directamente al constructor en el momento de instanciar la variable en mi fla.

Al principio me hice un lio porque no entendí el porque mi clase no me estaba aceptando los valores que le envíaba. Creo (y digo creo) que guarda algun tipo de relación con el haber no establecido como clase base a mi símbolo como flash.display.MovieCli. Digo esto porque lo más "raro" de todo es que si en lugar de tener mi clase en la carpeta en la que suelo guardar mis as. y por lo tanto guardando la clase como tsk.utils.ThumbObj en clase base y como myThumb en clase, lo guardo en misma carpeta que mi swf y lo llamo siemplemente ThumbObj en clase y SIN ninguna clase base, todo funciona perfecto!.

Sabes a que puede ser debido eso?, y bueno al respecto de lo que comentas al final de tu mensaje, ¿A qué te refieres con poner los argumentos por defecto?.

Gracias de nuevo, lo creas o no me has ayudado mucho.

Salu2.

tsk.

Por teskostudio

34 de clabLevel



 

firefox

 

Cristalab BabyBlue v4 + V4 © 2011 Cristalab
Powered by ClabEngines v4, HTML5, love and ponies.