|
|
|
Herencia II
Ahora que ya conocemos la idea de herencia y como funciona, en la programación orientada a objetos, veremos como podemos redefinir desde las subclases los métodos de la clase primaria que hayamos heredado o acceder de forma implícita a un método de la clase primaria una vez reimplementado desde la clase derivada. También explicaré muy brevemente como crear clases abstractas con métodos y propiedades genéricas para la utilización como plantilla, por las subclases. De esta forma podremos crear una interfaz con todos los métodos que utilizaría la aplicación para luego implementarlos una vez heredados.
Vamos a crear nosotros mismos la clase Animales con unas propiedades básicas que pueda tener todo animal.
|
Public Class Animales
Public color As String, peso As Integer, hambre As Boolean Public Overridable Sub SoyAnimal() Console.WriteLine("Soy un Animal (clase primaria)") End Sub
End Class
|
Una vez creada la clase base Animales ampliaremos más nuestra jerarquía, antes de heredar desde Gato, dividiendo a los animales en otra subclase a la que llamaremos Felinos :
|
Public Class FelinosInherits Animales Public Const NumeroPatas As Integer = 4 Public Dim Cola As Boolean = True Public Overrides Sub Soy() MyBase.Soy() Console.WriteLine("De la familia de los felinos") End Sub End Class
|
Felinos también contiene un método que substituye al de la clase primaria mediante el modificador Overrides. De esta forma cuando se llame al método Soy se ejecutará el nuevo método ampliado de la clase Felinos y no el de la clase primaria. Una vez sustituido ¿Sería posible ejecutar el código de la clase primaria? Sí, podemos acceder a la clase primaria implícitamente desde cualquier subclase utilizando la palabra clave MyBase. Así pues, aunque los métodos de la clase primaria hayan sido substituidos por otros siempre podremos acceder a ellos. Tendremos como una especie de sobrecarga de miembros con un mismo nombre pero implementaciones diferentes (debemos vigilar mucho la estructuración de las clases si no la herencia se nos volverá en nuestra contra y nuestra aplicación no evolucionará correctamente) :). NET también nos permite asegurarnos el acceso a un método de la misma clase y no a uno heredado. Para acceder a miembros de la misma clase utilizaremos la palabra clave MyClass.
Veamos el código que instanciará la clase Felinos.
|
Sub Main() Gato.Soy() Console.WriteLine(Gato.Npatas)
|
Con el siguiente resultado :
|
Soy un Animal (clase primaria) De la familia de los felinos 4
|
A diferencia del ejemplo en el artículo de Herencia tenemos un sólo método Soy que engloba a los anteriores (SoyA y SoyF) De esta forma hemos ampliado fácilmente un método heredado de la clase primaria sin tener que rescribir el código del método substituido ni que modificar nada de la clase primaria, acción que nos daría problemas si otra clase como por ejemplo "Reptiles" heredara el método Soy. También nos podemos encontrar en el caso que no deseemos que ninguna clase derivada nos substituya un método. En este caso utilizaremos el modificador NotOverridable o en el caso contrario MustOverridable si queremos que nuestro método deba ser substituido. ¿Por qué forzar a que un método sea substituido? Utilizaremos este modificador para las clases abstractas donde sólo definiremos métodos genéricos sin implementar y propiedades. De esta forma crearemos una interfaz que deberá ser seguida y complementada por todas las subclases que hereden de la clase abstracta. Siguiendo el ejemplo de los animales podríamos crear una clase abstracta donde definiríamos un método genérico MustOverridable Correr sin código. Las subclases que heredan de esta deben entonces implementar este método dependiendo del tipo de animal y su forma de correr. Si queremos asegurarnos de que todas las clases derivadas implementan nuestro nuevo método, podemos especificarlo con el modificador MustInherit en la declaración de la clase junto con MustOverridable en la declaración del método. La reutilización de código mediante herencia nos será muy útil siempre y cuando vigilemos la forma en la que estructuramos las clases para evitar la repetición de código o errores al modificar el comportamiento de los métodos heredados.
Una clase abstracta define las propiedades e interfaz de las subclases dando una pauta a seguir pero sin ninguna funcionalidad o método implementado. De esta forma podemos crear clases genéricas que se implementarán más tarde en las subclases. ¿Para qué sirve? Para crear aplicaciones estructuradas, fáciles de leer, permitiendo una mejor comunicación entre el equipo que la pueda programar. Veamos un ejemplo: Tenemos que empezar un nuevo proyecto donde simularemos diferentes comportamientos de Animales (que original). Para mantener todo estructurado que mejor que definir las propiedades en clases abstractas para luego implementarlas en cada grupo de animales:
|
Public Class AnimalesPublic Color As String, peso As Integer Public MustOverridable Sub Comer End Sub Public MustOverridable Sub Desplazarse End Sub End Class
Public Class AcuáticosInhertits Animales Public Aletas As Integer, AguaDulce As Boolean Public MustOverridable Sub Nadar End Sub End Class
Public Class DelfínInhertits Acuáticos Public Aletas As Integer, AguaDulce As Boolean Public Overrides Sub Nadar { Implementación de como Nada un delfín } End Sub Public Overrides Sub Comer { Implementación de como Come un delfín } End Sub
End Class
|
Hemos creado una estructura ordenada donde los animales heredarán la interfaz de clases abstractas y los métodos se implementarán en las subclases dónde estos serán comunes para las siguientes subclases (si existen más).
|
▲Volver a Título▲ ◄Índice principal► Timeless web site |
Este sitio se actualizó por última vez el 27 de diciembre de 2004