Documentación de Flash CS3 |
|||
| Programación con ActionScript 3.0 > El lenguaje ActionScript y su sintaxis > Tipos de datos > Verificación de tipos | |||
La verificación de tipos puede tener lugar al compilar o en tiempo de ejecución. Los lenguajes con tipos estáticos, como C++ y Java, realizan la verificación de tipos en tiempo de compilación. Los lenguajes con tipos dinámicos, como Smalltalk y Python, realizan la verificación de tipos en tiempo de ejecución. Al ser un lenguaje con tipos dinámicos, ActionScript 3.0 ofrece verificación de tipos en tiempo de ejecución, pero también admite verificación de tipos en tiempo de compilación con un modo de compilador especial denominado modo estricto. En modo estricto, la verificación de tipos se realiza en tiempo de compilación y en tiempo de ejecución; en cambio, en modo estándar la verificación de tipos sólo se realiza en tiempo de ejecución.
Los lenguajes con tipos dinámicos ofrecen una gran flexibilidad para estructurar el código, pero a costa de permitir que se produzcan errores de tipo en tiempo de ejecución. Los lenguajes con tipos estáticos notifican los errores de tipo en tiempo de compilación, pero a cambio deben conocer la información de tipos en tiempo de compilación.
La verificación de tipos en tiempo de compilación se suele favorecer en los proyectos grandes ya que, a medida que el tamaño de un proyecto crece, la flexibilidad de los tipos de datos suele ser menos importante que detectar los errores de tipo lo antes posible. Ésta es la razón por la que, de manera predeterminada, el compilador de ActionScript de Adobe Flash CS3 Professional y Adobe Flex Builder 2 está configurado para ejecutarse en modo estricto.
Para poder proporcionar verificación de tipos en tiempo de compilación, el compilador necesita saber cuáles son los tipos de datos de las variables o las expresiones del código. Para declarar explícitamente un tipo de datos para una variable, se debe añadir el operador dos puntos (:) seguido del tipo de datos como sufijo del nombre de la variable. Para asociar un tipo de datos a un parámetro, se debe utilizar el operador dos puntos seguido del tipo de datos. Por ejemplo, el código siguiente añade la información de tipo de datos al parámetro xParam y declara una variable myParam con un tipo de datos explícito:
function runtimeTest(xParam:String)
{
trace(xParam);
}
var myParam:String = "hello";
runtimeTest(myParam);
En modo estricto, el compilador de ActionScript notifica los tipos no coincidentes como errores de compilación. Por ejemplo, el código siguiente declara un parámetro de función xParam, de tipo Object, pero después intenta asignar valores de tipo String y Number a ese parámetro. Esto produce un error del compilador en modo estricto.
function dynamicTest(xParam:Object)
{
if (xParam is String)
{
var myStr:String = xParam; // error de compilación en modo estricto
trace("String: " + myStr);
}
else if (xParam is Number)
{
var myNum:Number = xParam; // error de compilación en modo estricto
trace("Number: " + myNum);
}
}
Sin embargo, incluso en modo estricto se puede evitar selectivamente la verificación de tipos en tiempo de compilación dejando sin tipo el lado derecho de una sentencia de asignación. También se puede marcar una variable o expresión como variable o expresión sin tipo, omitiendo una anotación de tipo o utilizando la anotación de tipo asterisco (*). Por ejemplo, si se modifica el parámetro xParam del ejemplo anterior de forma que ya no tenga una anotación de tipo, el código se compilará en modo estricto:
function dynamicTest(xParam)
{
if (xParam is String)
{
var myStr:String = xParam;
trace("String: " + myStr);
}
else if (xParam is Number)
{
var myNum:Number = xParam;
trace("Number: " + myNum);
}
}
dynamicTest(100)
dynamicTest("one hundred");
ActionScript 3.0 realiza la verificación de tipos en tiempo de ejecución tanto si se compila en modo estricto como si se compila en modo estándar. Considérese una situación en la que se pasa el valor 3 como argumento a una función que espera una matriz. En modo estricto, el compilador generará un error, ya que el valor 3 no es compatible con el tipo de datos Array. Si se desactiva el modo estricto y se ejecuta en modo estándar, el compilador no se quejará al detectar tipos no coincidentes, pero la verificación de tipos en tiempo de ejecución de Flash Player producirá un error en tiempo de ejecución.
En el siguiente ejemplo se muestra una función denominada typeTest() que espera un argumento de tipo Array pero recibe el valor 3. Esto provoca un error en tiempo de ejecución en modo estándar, ya que el valor 3 no es un miembro del tipo de datos (Array) declarado para el parámetro.
function typeTest(xParam:Array)
{
trace(xParam);
}
var myNum:Number = 3;
typeTest(myNum);
// error en tiempo de ejecución en el modo estándar de ActionScript 3.0
También puede haber situaciones en las que se produzca un error de tipo en tiempo de ejecución aunque se opere en modo estricto. Esto puede suceder si se usa el modo estricto pero se elige no verificar tipos en tiempo de compilación utilizando una variable sin tipo. Si se utiliza una variable sin tipo, no se elimina la verificación de tipos, sino que se aplaza hasta el tiempo de ejecución. Por ejemplo, si la variable myNum del ejemplo anterior no tiene un tipo de datos declarado, el compilador no puede detectar la discordancia de tipos, pero Flash Player generará un error en tiempo de ejecución porque compara el valor en tiempo de ejecución de myNum, que está establecido en 3 como resultado de la sentencia de asignación, con el tipo de xParam, que está establecido en el tipo de datos Array.
function typeTest(xParam:Array)
{
trace(xParam);
}
var myNum = 3;
typeTest(myNum);
// error en tiempo de ejecución en ActionScript 3.0
La verificación de tipos en tiempo de ejecución también permite un uso más flexible de la herencia que la verificación en tiempo de compilación. Al aplazar la verificación de tipos al tiempo de ejecución, el modo estándar permite hacer referencia a propiedades de una subclase aunque se realice una conversión hacia arriba. Una conversión hacia arriba se produce si se utiliza una clase base para declarar el tipo de una instancia de la clase y una subclase para crear la instancia. Por ejemplo, se puede crear una clase denominada ClassBase ampliable (las clases con el atributo final no se pueden ampliar):
class ClassBase
{
}
Posteriormente se puede crear una subclase de ClassBase denominada ClassExtender, con una propiedad denominada someString, como se indica a continuación:
class ClassExtender extends ClassBase
{
var someString:String;
}
Se pueden usar ambas clases para crear una instancia de clase que se declara con el tipo de datos de ClassBase, pero se crea con el constructor de ClassExtender. Una conversión hacia arriba se considera una operación segura porque la clase base no contiene ninguna propiedad o método que no esté en la subclase.
var myClass:ClassBase = new ClassExtender();
No obstante, una subclase contiene propiedades o métodos que la clase base no contiene. Por ejemplo, la clase ClassExtender contiene la propiedad someString, que no existe en la clase ClassBase. En el modo estándar de ActionScript 3.0 se puede hacer referencia a esta propiedad mediante la instancia de myClass sin generar un error de tiempo de compilación, como se muestra en el siguiente ejemplo:
var myClass:ClassBase = new ClassExtender(); myClass.someString = "hello"; // ningún error en el modo estándar de ActionScript 3.0
El operador is, una de las novedades de ActionScript 3.0, permite comprobar si una variable o expresión es un miembro de un tipo de datos determinado. En versiones anteriores de ActionScript el operador instanceof proporcionaba esta funcionalidad, pero en ActionScript 3.0 no se debe utilizar el operador instanceof para comprobar la pertenencia a un tipo de datos. Para la verificación manual de tipos se debe utilizar el operador is en lugar del operador instanceof, ya que la expresión x instanceof y simplemente comprueba en la cadena de prototipos de x si existe y (y en ActionScript 3.0, la cadena de prototipos no proporciona una imagen completa de la jerarquía de herencia).
El operador is examina la jerarquía de herencia adecuada y se puede utilizar no sólo para verificar si un objeto es una instancia de una clase específica, sino también en el caso de que un objeto sea una instancia de una clase que implementa una interfaz determinada. En el siguiente ejemplo se crea una instancia de la clase Sprite denominada mySprite y se utiliza el operador is para comprobar si mySprite es una instancia de las clases Sprite y DisplayObject, y si implementa la interfaz IEventDispatcher.
var mySprite:Sprite = new Sprite(); trace(mySprite is Sprite); // true trace(mySprite is DisplayObject); // true trace(mySprite is IEventDispatcher); // true
El operador is comprueba la jerarquía de herencia y notifica que mySprite es compatible con las clases Sprite y DisplayObject (la clase Sprite es una subclase de la clase DisplayObject). También comprueba si mySprite hereda de las clases que implementan la interfaz IEventDispatcher. Como la clase Sprite hereda de la clase EventDispatcher, que implementa la interfaz IEventDispatcher, el operador is notifica correctamente que mySprite implementa la misma interfaz.
En el siguiente ejemplo se muestran las mismas pruebas del ejemplo anterior, pero con instanceof en lugar del operador is. El operador instanceof identifica correctamente que mySprite es una instancia de Sprite o DisplayObject, pero devuelve false cuando se usa para comprobar si mySprite implementa la interfaz IEventDispatcher.
trace(mySprite instanceof Sprite); // true trace(mySprite instanceof DisplayObject); // true trace(mySprite instanceof IEventDispatcher); // false
El operador as, una de las novedades de ActionScript 3.0, también permite comprobar si una expresión es un miembro de un tipo de datos determinado. Sin embargo, a diferencia del operador is, el operador as no devuelve un valor booleano. El operador as devuelve el valor de la expresión en lugar de true y null en lugar de false. En el siguiente ejemplo se muestran los resultados de utilizar el operador as en lugar del operador is en el caso sencillo de comprobar si una instancia de Sprite es un miembro de los tipos de datos DisplayObject, IEventDispatcher y Number.
var mySprite:Sprite = new Sprite(); trace(mySprite as Sprite); // [object Sprite] trace(mySprite as DisplayObject); // [object Sprite] trace(mySprite as IEventDispatcher); // [object Sprite] trace(mySprite as Number); // null
Al utilizar el operador as, el operando de la derecha debe ser un tipo de datos. Si se intenta utilizar una expresión que no sea un tipo de datos como operando de la derecha se producirá un error.
Flash CS3
Enviarme un mensaje de correo electrónico cuando se añadan comentarios a esta página | Informe de comentarios
Página actual: http://livedocs.adobe.com/flash/9.0_es/main/00000045.html