Home » AS3 »Avanzado »Class »POO »Tutoriales » Currently Reading:

Programación orientada a objetos: Herencia de clases.

febrero 1, 2009 AS3, Avanzado, Class, POO, Tutoriales No Comments
Programación orientada a objetos: Herencia de clases.

La herencia de clases es uno de los conceptos básicos de la programación orientada a objetos. Decir que una clase hereda de otra quiere decir que esa clase obtiene los mismos métodos y propiedades de la otra clase. Permitiendo de esta forma añadir a las características heredadas las suyas propias.

Supongamos que tenemos una clase “Persona” con los métodos y propiedades básicas de una objeto persona como podrian ser “caminar” o “hablar”, podríamos tener otras clases como “Guillermo” o “Elder” que comparten todas las características de una “Persona” pero que añaden características propias. Por lo que “Guillermo” y “Elder” pueden realizar las

mismas funciones que puede realizar una “Persona” y además cada una puede realizar las suyas propias, por ejemplo, “Guillermo” sabe nadar pero “Elder” no, y “Elder” sabe bailar reggeton pero “Guillermo” no.

En terminos de programación estaríamos diciendo que “Guillermo” y “Elder” son dos clases especializadas que heredan o extienden de la superclase “Persona”.

Tipos de herencia de clases

Existen dos tipos de herencia:

  • Herencia por especialización
  • Herencia por generalización

En realidad la herencia es la misma, esta es una diferenciación puramente conceptual sobre la forma en que se a llegado a ella.

Una herencia por especialización es la que se realiza cuando necesitamos crear una clase nueva que disponga de las mismas características que otra pero que le añada funcionalidades. Por ejemplo si tenemos una clase que genera un botón simple, y necesitamos crear un botón que sea igual que el anterior pero que además añada un efecto al ser clicado.

La herencia por generalización es la que realizamos cuando tenemos muchas clases que comparten unas mismas funcionalidades y por homogeneizar las partes comunes se decide crear una clase que implemente toda esa parte común y se dejan solo las partes especificas en cada clase. Por ejemplo si tenemos clases para dibujar formas geométricas todas ellas

disponen de las mismas propiedades (un color de fondo, color de linea, etc..), todas estas características pueden estar en una clase general de la que hereden todas las clases concretas, evitando tener que escribir todo ese código común en todas ellas.

Herencia de clases en Actionscript

En Actionscript definimos que una clase hereda de otra con la sentencia “extends“.

  1. public class Guillermo extends Persona

Public, private o protected

Una consideración a tener en cuenta de la herencia es que una clase no hereda la propiedades o métodos privados, con lo que no tendrán acceso a ellas. Si necesitamos heredar propiedades o métodos que no queremos que sean accesibles desde fuera de las clases las definiremos como protected.

Sobreescritura de métodos

Una característica muy importante que permite la herencia es que podemos hacer que una clase implemente de manera diferente un método heredado. Haciendo que dos clases que heredan de la misma clase y heredan los mismos métodos se comporten de maneras diferentes.

Por ejemplo, unas clases de dibujo de figuras geométricas pueden heredar de una clase general la función “dibujar”. Todas las clases dispondrán de esa función, pero cada clase la implementará de diferente manera y por lo tanto dibujará una figura diferente.

Para sobrescribir un método de la superclase utilizaremos la sentencia override en la definición del método.

  1. //función de la superclase
  2. public function traza():void
  3. {
  4.     trace("superclase");
  5. }
  1. //función de la subclase
  2. override public function traza():void
  3. {
  4.     trace("subclase");
  5. }

De esta manera al ejecutar la función “traza()” desde una subclase obtendremos el texto “subclase” sobrescribiendo las acciones del método de la subclase (no obtendríamos el texto “superclase”).

En el caso de no querer sobrescribir por completo toda la implementación del método de la superclase, si no que lo que queremos es ampliarlo, podemos acceder a la implementación de la superclase con el operador “super”.

  1. //función de la subclase
  2. override public function traza():void
  3. {
  4.     super.traza();
  5.     trace("subclase");
  6. }

En este caso, se ejecutaría la implementación del método en la superclase (obtendriamos el texto “superclase”) y luego el de la subclase (obtendríamos también el texto “subclase”).

Esto también lo podemos realizar en el constructor de la clase. Es bastante probable que una clase esté definiendo valores dentro de su constructor, de manera que al ser extendida nos interese que esas definiciones se continúen realizando. En este caso deberemos realizar una llamada al constructor de la superclase a través del operador “super”.

  1. package
  2. {
  3.     public class A
  4.     {
  5.         protected var variable:uint;
  6.        
  7.         public function A(n:uint)
  8.         {
  9.             variable = n;
  10.         }
  11.     }
  12. }
  1. package
  2. {
  3.     import A;
  4.  
  5.     public class B extends A
  6.     {
  7.         public function B(n:uint)
  8.         {
  9.             super(n); //ejecuta el contructor de la clase A, enviandole el parámetro
  10.         }
  11.     }
  12. }

En el caso de que queramos asegurarnos de que una propiedad o método no pueda ser sobrescrita por otra clase la definiremos como final.

  1. //función de la subclase que no permitirá ser sobreescrita
  2. public final function traza():void
  3. {
  4.     trace("subclase");
  5. }

Ejemplo del uso de herencia de clases:

Veamos un sencillo ejemplo práctico: Crearemos un par de clases muy simples para dibujar un cuadrado o un círculo.

Lógicamente el primer paso es pensar que características compartirán tanto los cuadrados y los círculos.

  • Ambos son elementos gráficos que tienen propiedades que definen su tamaño (size), si disponen de relleno o solo de línea (fill), el color de relleno (bgColor), el grosor de linea (borderSize) y el color de la linea (borderColor).
  • Tambien ambás dispondrán de una función que permitirá actualizar el gráfico en caso de modificar sus propiedades.
  • Por último amb´s dispondran de la método que dibujará el gráfico. Lógicamente esta será la función que cada clase implementará de forma diferente.

Así que lo que haremos es crear una superclase “Grafico” que disponga de todas las propiedades mencionadas anteriormente, y dejaremos la implementación del método “dibuja()” a las subclases “Cuadrado” y “Circulo”.

Empecemos escribiendo la interface de métodos públicos que deberán disponer todos los objetos que extiendan de “Grafico”. En este caso serán todos los setters y getters para las propiedades, y el método para actualizar el gráfico.

  1. package org.cristalab.graphics
  2. {
  3.     public interface IGrafico
  4.     {
  5.         function get size():uint
  6.         function set size(n:uint):void
  7.         function get fill():Boolean
  8.         function set fill(n:Boolean):void
  9.         function get bgColor():uint
  10.         function set bgColor(n:uint):void
  11.         function get borderSize():uint
  12.         function set borderSize(n:uint):void
  13.         function get borderColor():uint
  14.         function set borderColor(n:uint):void
  15.         function update():void
  16.     }
  17. }

Escribiremos la superclase “Grafico” que implementará la interface “IGrafico” y definirá todos los setters y getters de las propiedades.

Las propiedades las definiremos como “portected” para que sean privadas pero heredables.

El constructor de la clase recibirá todos los parámetros necesarios para definir las propiedades (les asignaremos valores por defecto por si se crea una instancia sin pasarle parámetros). Y realizará una llamada a la función “dibuja()” que es la que creará el gráfico.

  1. package org.cristalab.graphics
  2. {
  3.     import flash.display.Shape;
  4.     import flash.display.Sprite;
  5.     import org.cristalab.graphics.IGrafico;
  6.     //------------------------------------------------------------------------
  7.     public class Grafico extends Sprite implements IGrafico
  8.     {
  9.         protected var _size:uint;
  10.         protected var _fill:Boolean;
  11.         protected var _bgColor:uint;
  12.         protected var _borderSize:uint;
  13.         protected var _borderColor:uint;
  14.         //------------------------------------------------------------------------
  15.         public function Grafico(size:uint = 10, fill:Boolean = true, bgColor:uint = 0x000000, borderSize:uint = 0, borderColor:uint = 0x000000)
  16.         {
  17.             _size = size;
  18.             _fill = fill;
  19.             _bgColor = bgColor;
  20.             _borderSize = borderSize;
  21.             _borderColor = borderColor;
  22.             dibuja();
  23.         }
  24.         //------------------------------------------------------------------------
  25.         public function get size():uint
  26.         {
  27.             return _size;
  28.         }
  29.         public function set size(n:uint):void
  30.         {
  31.             _size = n;
  32.         }
  33.         //------------------------------------------------------------------------
  34.         public function get fill():Boolean
  35.         {
  36.             return _fill;
  37.         }
  38.         public function set fill(n:Boolean):void
  39.         {
  40.             _fill = n;
  41.         }
  42.         //------------------------------------------------------------------------
  43.         public function get bgColor():uint
  44.         {
  45.             return _size;
  46.         }
  47.         public function set bgColor(n:uint):void
  48.         {
  49.             _bgColor = n;
  50.         }
  51.         //------------------------------------------------------------------------
  52.         public function get borderSize():uint
  53.         {
  54.             return _borderSize;
  55.         }
  56.         public function set borderSize(n:uint):void
  57.         {
  58.             _borderSize = n;
  59.         }
  60.         //------------------------------------------------------------------------
  61.         public function get borderColor():uint
  62.         {
  63.             return _borderColor;
  64.         }
  65.         public function set borderColor(n:uint):void
  66.         {
  67.             _borderColor = n;
  68.         }
  69.         //------------------------------------------------------------------------
  70.         public function update():void
  71.         {
  72.             this.graphics.clear();
  73.             dibuja();
  74.         }
  75.         //------------------------------------------------------------------------
  76.         protected function dibuja():void
  77.         {
  78.             Throw.newError("clase abstracta");
  79.         }
  80.         //------------------------------------------------------------------------
  81.     }
  82. }

Como hemos dicho, la clase “Grafico” no implementa el método “dibuja()” ya que eso depende de cada subclase, con lo que si intentamos crear una instancia de “Grafico” nos lanzará un error. Lo único que hacemos es definir que todas las subclases hereden el método y cada una lo implenete a su manera.

Escribamos ahora la clase “Cuadrado”.

Esta clase extendrá de la clase “Grafico” e implementará la interface “IGrafico”. Por lo tanto heredará todas las propiedades y métodos de la superclase marcados como public o protected, con lo que no necesitaremos definir las protiedades ni los setter y getters, pero dispondrá de ellos.

El constructor de esta clase recibirá como parámetros los valores del objeto a crear, y deberemos pasarselos al constructor de la superclase para que asigne los valores y ejecute la función de dibujar. Como hemos mencionado esto lo haremos utilizando la sentencia super();

Ahora solo nos quedará sobreescribir el método “dibuja()” para que se dibuje lo que nos interese en función de la clase actual, en este caso queremo sdibujar un cuadrado. Utilizaremos un override para sobrescribir el método.

  1. package org.cristalab.graphics
  2. {
  3.     import org.cristalab.graphics.IGrafico;
  4.     import org.cristalab.graphics.Grafico;
  5.     import flash.display.Shape;
  6.     import flash.display.Sprite;
  7.     //------------------------------------------------------------------------
  8.     public class Cuadrado extends Grafico implements IGrafico
  9.     {
  10.         //------------------------------------------------------------------------
  11.         public function Cuadrado(size:uint = 10, fill:Boolean = true, bgColor:uint = 0x000000, borderSize:uint = 0, borderColor:uint = 0x000000)
  12.         {
  13.             super(size, fill, bgColor, borderSize, borderColor);
  14.         }
  15.         //------------------------------------------------------------------------
  16.         override protected function dibuja():void
  17.         {
  18.             if (_fill == true)
  19.             {
  20.                 this.graphics.beginFill(_bgColor);
  21.             }
  22.             if (_borderSize != 0)
  23.             {
  24.                 this.graphics.lineStyle(_borderSize, _borderColor);
  25.             }
  26.             this.graphics.drawRect(0, 0, _size, _size);
  27.             if (_fill == true)
  28.             {
  29.                 this.graphics.endFill();
  30.             }
  31.         }
  32.         //------------------------------------------------------------------------
  33.     }
  34. }

Haremos lo mismo para la clase “Circulo”. Únicamente deberemos implementar de diferente manera el método “dibuja”.

  1. package org.cristalab.graphics
  2. {
  3.     import org.cristalab.graphics.IGrafico;
  4.     import org.cristalab.graphics.Grafico;
  5.     import flash.display.Shape;
  6.     import flash.display.Sprite;
  7.     //------------------------------------------------------------------------
  8.     public class Circulo extends Grafico implements IGrafico
  9.     {
  10.         //------------------------------------------
  11.         public function Circulo(size:uint = 10, fill:Boolean = true, bgColor:uint = 0x000000, borderSize:uint = 0, bordeColor:uint = 0x000000)
  12.         {
  13.             super(size, fill, bgColor, borderSize, borderColor);
  14.         }
  15.         //------------------------------------------------------------------------
  16.         override protected function dibuja():void
  17.         {
  18.             if (_fill == true)
  19.             {
  20.                 this.graphics.beginFill(_bgColor);
  21.             }
  22.             if (_borderSize != 0)
  23.             {
  24.                 this.graphics.lineStyle(_borderSize, _borderColor);
  25.             }
  26.             var radio:uint = Math.round(_size / 2);
  27.             this.graphics.drawCircle(radio, radio, radio);
  28.             if (_fill == true)
  29.             {
  30.                 this.graphics.endFill();
  31.             }
  32.         }
  33.         //------------------------------------------------------------------------
  34.     }
  35. }

A partir de aquí iremos creando tantas clases como gráficos diferentes nos interese dibujar, incluso podemos extender estas subclases en otras subclases, por ejemplo para crear objetos más complejos pero que su base sea un cuadrado o un circulo.

Compártelo:

Programación orientada a objetos: Herencia de clases.
Visto 9.111 veces

Comment on this Article:








Twitter: zguillez

AdvertisementAdvertisementAdvertisementAdvertisement

Recibe las novedades por email

Post destacado

Cómo conectar una aplicación Flash con una base de datos a través de PHP

27 dic 2013

En este post mostraré como comunicar una aplicación Flash/AIR con una base de datos MySQL a través de un fichero PHP en el servidor. Para realizar acciones como, por ejemplo, enviar puntuaciones de juegos, visializar rankings o enviar registros. En la parte de Flash crearemos una clase de Actionscript 3 que realizará el envío de variables a través de las clases URLLoader y URLVariables. package org.codigoactionscript.data { import flash.net.URLRequestMethod; import flash.net.URLVariables; import flash.events.Event; import flash.events.EventDispatcher; import flash.net.URLLoader; import flash.net.URLRequest; //—————————————————— public class PHPVarsData extends EventDispatcher { public static var CARGADO:String = "DATA_CARGADA"; public static var ERROR:String = "DATA_ERROR"; protected var …



Map

Ranking

Codigoactionscript.org: 4.65 sobre 5 (106 valoraciones)

twitter-widget.com