Todas las subclases heredan una propiedad de instancia definida con la palabra clave function, var o const, con tal de que no se haya declarado la propiedad con el atributo private en la clase base. Por ejemplo, la clase Event en ActionScript 3.0 tiene diversas subclases que heredan propiedades comunes a todos los objetos de evento.
Para algunos tipos de eventos, la clase Event contiene todas las propiedades necesarias para definir el evento. Estos tipos de eventos no requieren más propiedades de instancia que las definidas en la clase Event. Algunos ejemplos de estos eventos son el evento complete, que se produce cuando los datos se han cargado correctamente, y el evento connect, que se produce cuando se establece una conexión de red.
El ejemplo siguiente es un fragmento de la clase Event que muestra algunas de las propiedades y los métodos que heredarán las subclases. Como las propiedades se heredan, una instancia de cualquier subclase puede acceder a estas propiedades.
public class Event
{
public function get type():String;
public function get bubbles():Boolean;
...
public function stopPropagation():void {}
public function stopImmediatePropagation():void {}
public function preventDefault():void {}
public function isDefaultPrevented():Boolean {}
...
}
Otros tipos de eventos requieren propiedades únicas que no están disponibles en la clase Event. Estos eventos se definen creando subclases de la clase Event para añadir nuevas propiedades a las propiedades definidas en la clase Event. Un ejemplo de una subclase de este tipo es la clase MouseEvent, que añade propiedades únicas a eventos asociados con el movimiento o los clics del ratón, como los eventos mouseMove y click. El ejemplo siguiente es un fragmento de la clase MouseEvent que muestra la definición de propiedades que se han añadido a la subclase y, por tanto, no existen en la clase base:
public class MouseEvent extends Event
{
public static const CLICK:String= "click";
public static const MOUSE_MOVE:String = "mouseMove";
...
public function get stageX():Number {}
public function get stageY():Number {}
...
}
Herencia y especificadores de control de acceso
Si una propiedad se declara con la palabra clave public, estará visible en cualquier parte del código. Esto significa que la palabra clave public, a diferencia de las palabras clave private, protected e internal, no restringe de ningún modo la herencia de propiedades.
Si se declara una propiedad con la palabra clave private, sólo será visible en la clase que la define, lo que significa que ninguna subclase la heredará. Este comportamiento es distinto del de las versiones anteriores de ActionScript, en las que el comportamiento de la palabra clave private era más parecido al de la palabra clave protected de ActionScript 3.0.
La palabra clave protected indica que una propiedad es visible en la clase que la define y en todas sus subclases. A diferencia de la palabra clave protected del lenguaje de programación Java, la palabra clave protected de ActionScript 3.0 no hace que una propiedad esté visible para todas las clases de un mismo paquete. En ActionScript 3.0 sólo las subclases pueden acceder a una propiedad declarada con la palabra clave protected. Además, una propiedad protegida estará visible para una subclase tanto si la subclase está en el mismo paquete que la clase base como si está en un paquete distinto.
Para limitar la visibilidad de una propiedad al paquete en el que se define, se debe utilizar la palabra clave internal o no utilizar ningún especificador de control de acceso. Cuando no se especifica ninguno especificador de control de acceso, el predeterminado es internal. Una propiedad marcada como internal sólo podrá ser heredada por una subclase que resida en el mismo paquete.
Se puede utilizar el ejemplo siguiente para ver cómo afecta cada uno de los especificadores de control de acceso a la herencia más allá de los límites del paquete. El código siguiente define una clase principal de aplicación denominada AccessControl y otras dos clases denominadas Base y Extender. La clase Base está en un paquete denominado foo y la clase Extender, que es una subclase de la clase Base, está en un paquete denominado bar. La clase AccessControl sólo importa la clase Extender y crea una instancia de Extender que intenta acceder a una variable denominada str definida en la clase Base. La variable str se declara como public de forma que el código se compile y ejecute como se indica en el siguiente fragmento:
// Base.as in a folder named foo
package foo
{
public class Base
{
public var str:String = "hello"; // change public on this line
}
}
// Extender.as in a folder named bar
package bar
{
import foo.Base;
public class Extender extends Base
{
public function getString():String {
return str;
}
}
}
// main application class in file named AccessControl.as
package
{
import flash.display.MovieClip;
import bar.Extender;
public class AccessControl extends MovieClip
{
public function AccessControl()
{
var myExt:Extender = new Extender();
trace(myExt.str);// error if str is not public
trace(myExt.getString()); // error if str is private or internal
}
}
}
Para ver cómo afectan los otros especificadores de control de acceso a la compilación y la ejecución del ejemplo anterior, se debe cambiar el especificador de control de acceso de la variable str a private, protected o internal después de eliminar o marcar como comentario la línea siguiente de la clase AccessControl:
trace(myExt.str);// error if str is not public
No se permite la sustitución de variables
Las propiedades declaradas con la palabra clave var o const se pueden heredar, pero no se pueden sustituir. Para sustituir una propiedad hay que redefinirla en una subclase. El único tipo de propiedad que se puede sustituir son los descriptores de acceso get y set (es decir, propiedades declaradas con la palabra clave function). Aunque no es posible sustituir una variable de instancia, se puede obtener una funcionalidad similar creando métodos captador y definidor para la variable de instancia y sustituyendo los métodos.