Herencia
El propósito principal de la herencia es el de organizar mejor las clases que componen una determinada realidad, y poder agruparlas en función de atributos y comportamientos comunes a la vez que cada una se especializa según sus particularidades.
Cabe aclarar además que hay dos tipos de herencias:
- Herencia Simple: una clase derivada puede heredar sólo de una clase base (los lenguajes .NET soportan este tipo de herencia)
- Herencia Múltiple: una clase derivada puede heredar de una o más clases base (C++ es un ejemplo de lenguaje que soporta este tipo de herencia).
Herencia “Es-Un”: herencia real, donde la subclase es un tipo específico de la superclase
- Un Cuadrado es un Rectángulo
- Un perro es un mamífero
- Un automóvil es un vehículo a motor
Interfaz - Recurso de diseño soportado por los lenguajes orientados a objetos que permite definir comportamiento
- Permite que clases que no están estrechamente relacionadas entre sí deban tener el mismo comportamiento
- La implementación de una interfaz es un contrato que obliga a la clase a implementar todos los métodos definidos en la interfaz
Polimorfismo - Es la propiedad que tienen los objetos de permitir invocar genéricamente un comportamiento (método) cuya implementación será delegada al objeto correspondiente recién en tiempo de ejecución
- El polimorfismo tiende a existir en las relaciones de herencia, pero no siempre es así
Aquí tenemos un ejemplo práctico de la implementación de polimorfismo en un diseño orientado a objetos. Por un lado tenemos la clase base “Transporte”, que posee los métodos “Avanzar” y “Frenar”. Por otro lado tenemos tres clases distintas derivadas de la clase “Transporte”, cada una de las cuales podrá sobrescribir la implementación de los métodos Avanzar y Frenar para que su comportamiento sea más específico.
Ahora bien, como todas heredan de la misma clase base, las clases derivadas pueden ser tratadas genéricamente. Esto quiere decir que podríamos tener un array que almacene objetos de tipo Transporte, y recorrerlo luego para llamar al método “Avanzar” de cada uno. De esta forma, en tiempo de codificación es imposible saber a qué método “Avanzar” se está llamando en realidad (al del Auto? Al del caballo? Al del transbordador?), sino que esta decisión es tomada en tiempo de ejecución en base al tipo particular de objeto que esté instanciado.
En pseudocódigo, esto se escribiría de la siguiente manera:
Definir arrayTransportes (3) de tipo Transporte
arrayTransportes(1) = nuevo Automóvil() //Un automóvil ES UN TIPO DE transporte
arrayTransportes(2) = nuevo Transbordador() //Un Transbordador ES UN TIPO DE transporte
arrayTransportes(3) = nuevo Caballo() //Un Caballo ES UN TIPO DE transporte
Por Cada (Transporte t en arrayTransportes)
t.Avanzar()
t.Frenar()
Fin