Ir al contenido principal


HERENCIA  Y  POLIMORFISMO


Polimorfismo en Programación Orientada a Objetos

Introducción :


• Se pueden definir jerarquías de clases, con clases generales que definen el comportamiento común a unos objetos y clases específicas que sólo añaden o redefinen el comportamiento propio, único, de ese objeto respecto a la clase general. 
• Clases bases y clases derivadas.

concepto:

El concepto de polimorfismo es en realidad algo muy básico. Realmente, cuando estamos aprendiendo Programación Orientada a Objetos (también conocida por sus siglas POO / OOP) muchos estudiantes nos hacemos un embolado tremendo al tratar de entender el concepto, pero en su base es algo extremadamente sencillo.
Trataremos de explicarlo en este artículo con palabras sencillas, pero para los valientes, aquí va una primera definición que no es mía y que carece de la prometida sencillez. Pero no te preocupes, pues la entiendas o no, luego lo explicaré todo de manera más llana.

Herencia y las clasificaciones en Programación Orientada a Objetos

Para poder entender este concepto de OOP necesitas entender otras cosas previas, como es el caso de la herencia. Esto lo hemos explicado en un artículo anterior en DesarrolloWeb.com: Herencia en la Programación Orientada a Objetos.
Veremos que el polimorfismo y la herencia son dos conceptos estrechamente ligados. Conseguimos implementar polimorfismo en jerarquías de clasificación que se dan a través de la herencia. Por ejemplo, tenemos una clase vehículo y de ella dependen varias clases hijas como coche, moto, autobús, etc.

Por qué el sistema de tipos es importante en Polimorfismo

Muchos de los lectores que asumo se introducen en el concepto de polimorfismo a través de este artículo han aprendido a programar en lenguajes débilmente tipados, como es el caso de PHP y Javascript. Por ello es conveniente entender cómo es un lenguaje fuertemente tipado, como es el caso de Java o C.

Polimorfismo en objetos

Ahora párate a pensar en clases y objetos. Quédate con esto: Tal como funcionan los lenguajes fuertemente tipados, una variable siempre deberá apuntar a un objeto de la clase que se indicó en el momento de su declaración. Una función cuyo parámetro se haya declarado de una clase, sólo te aceptará recibir objetos de esa clase. Un array que se ha declarado que es de elementos de una clase determinada, solo aceptará que rellenemos sus casillas con objetos de esa clase declarada.

Para qué nos sirve en la práctica el polimorfismo

Volvamos a la clase "Largometraje" y ahora pensemos en la clase "Cine". En un cine se reproducen largometrajes. Puedes, no obstante, tener varios tipos de largometrajes, como películas o documentales, etc. Quizás las películas y documentales tienen diferentes características, distintos horarios de audiencia, distintos precios para los espectadores y por ello has decidido que tu clase "Largometraje" tenga clases hijas o derivadas como "Película" y "Documental".

Tipos de polimorfismo

Polimorfismo de sobrecarga

El polimorfismo de sobrecarga ocurre cuando las funciones del mismo nombre existen, con funcionalidad similar, en clases que son completamente independientes una de otra (éstas no tienen que ser clases secundarias de la clase objeto). Por ejemplo, la clase complex, la clase image y la clase link pueden todas tener la función "display". Esto significa que no necesitamos preocuparnos sobre el tipo de objeto con el que estamos trabajando si todo lo que deseamos es verlo en la pantalla.

Polimorfismo paramétrico(también llamado polimorfismo de plantillas)

El polimorfismo paramétrico es la capacidad para definir varias funciones utilizando el mismo nombre, pero usando parámetros diferentes (nombre y/o tipo). El polimorfismo paramétrico selecciona automáticamente el método correcto a aplicar en función del tipo de datos pasados en el parámetro.
Por lo tanto, podemos por ejemplo, definir varios métodos homónimos de addition() efectuando una suma de valores.
    *El método int addition (int,int) devolvería la suma de dos números enteros.
    *El método float addition (float, float) devolvería la suma de dos flotantes.
    *El método char addition (char, char) daría por resultado la suma de dos caracteres definidos por el autor.
Una signature es el nombre y tipo (estático) que se da a los argumentos de una función. Por esto, una firma de método determina qué elemento se va a llamar.

Polimorfismo de inclusión (también llamado redefinición o subtipado)

La habilidad para redefinir un método en clases que se hereda de una clase base se llama especialización. Por lo tanto, se puede llamar un método de objeto sin tener que conocer su tipo intrínseco: esto es polimorfismo de subtipado. Permite no tomar en cuenta detalles de las clases especializadas de una familia de objetos, enmascarándolos con una interfaz común (siendo esta la clase básica).

Diferencias entre Polimorfismos y Sobrecarga

  • El polimorfismo, suele ser bastante ventajoso aplicado desde las interfaces, ya que permite crear nuevos tipos sin necesidad de tocar las clases ya existentes (imaginemos que deseamos añadir una clase Multiplicar), basta con recompilar todo el código que incluye los nuevos tipos añadidos. Si se hubiera recurrido a la sobrecarga durante el diseño exigiría retocar la clase anteriormente creada al añadir la nueva operación Multiplicar, lo que además podría suponer revisar todo el código donde se instancia a la clase.
  • La sobrecarga se da siempre dentro de una sola clase, mientras que el polimorfismo se da entre clases distintas.
  • Un método está sobrecargado si dentro de una clase existen dos o más declaraciones de dicho método con el mismo nombre pero con parámetros distintos, por lo que no hay que confundirlo con polimorfismo.
  • En definitiva: La sobrecarga se resuelve en tiempo de compilación utilizando los nombres de los métodos y los tipos de sus parámetros; el polimorfismo se resuelve en tiempo de ejecución del programa, esto es, mientras se ejecuta, en función de que clase pertenece un objeto.


ALGUNOS EJEMPLOS DE POLIMORFISMO

Ejemplos (I) 

• Clase Persona (fecha nac., DNI, dir., tel.)
          – Jefe (despacho, incentivos, ...)
          – Vendedor (área, clientes,...)
          – Secretarios 
• Clase Forma: área (?), perímetro (?), color 
          – Rectángulo: dos lados, área, perímetro.
          – Cuadrado: un lado, área, perímetro. 
          – Elipse: dos radios, área 
          – Circulo: Un radio, área, circunferencia 
• Clasificación Animales (“es un ..”)

Ejemplos (II) 


• Clase Vehículos: Peso, Potencia, Cilindrada 
          – Coches: Nº puertas, extras 
                  • Monovolúmenes 
                  • Deportivos. 
                  • Furgonetas 
          – Camiones: PMA, Tara, Nº ejes. 
                  • Rígidos 
                  • Con remolque 
          – Motocicletas. 
                  • Con matrícula 
                  • Sin matrícula


Control de Acceso 


• Hay tres posibilidades respecto a la Base: 
        – Private: Solo se usan en la clase en cuestión. 
        – Protected: Se usan en esa clase y sus hijas. 
        – Public: Se puede usar fuera de la clase. 
• Se aplica el más restrictivo entre el definido en la clase base y el de acceso a la misma. 
• Ej: class derivada: public base { ... }

Herencia 

• Se hereda todo, atributos y métodos. 
• Con las restricciones de acceso comentadas. 
• Si un método cambia su comportamiento puede redefinirse. Puede invocar al padre:                                               cuadrado::imprimir () { 
                    forma::imprimir(); 
                    cout << “ con lado “ << lado; 
• Si no se redefine usa el método del padre.

Sustitución de métodos 


class D: public B { … }; 
• Clase D puede reutilizar, extender o crear su 
        propia definición de método M de B 
• Para sustituir la implementación 
        de M de B, lo define de nuevo 
• Si lo extiende, 
         – desde M de D puede invocar M de B 
• Pero usando el operador de ámbito B::M 
• Si desea reutilizarlo no debe hacer nada.

EJEMPLO 
------ todos los animales comen algo, pero algunos comen carne, otros hierbitas, otros se comen entre si, etc. 

class animal { 
metodo comer() 


class carnivoro => es un animal { 
redefine metodo comer() { come carne } 


class herbivoro => es un animal { 
redefine metodo comer() { come hierba } 


class omnivoro => es un animal { 
redefine metodo comer() { como de todo } 


animal leon, tortuga 
leon = new carnivoro 
tortuga = new herbivoro 
leon.comer 
toruga.comer 

- -----todas las personas tienen un color de piel, pero algunos son negritos, otros amarillos, otros blancos, otros rojos, otros verdes, otros azules, otros color #548762, etc. 

class personita { 
metodo colordepiel() 


class negrito: es una personita { 
redefine metodo colordepiel() { es negrito } 


class indito: es una personita { 
redefine metodo colordepiel() { es un indito } 


personita manuel, juan, pepita, lulu 
lulu = new negrito 
pepita = new indito 
... 
manuel.colordepiel, etcétera. 

------------ejemplo


En este ejemplo haremos uso del lenguaje C++ para mostrar el polimorfismo. También se hará uso de las funciones virtuales puras de este lenguaje, aunque para que el polimorfismo funcione no es necesario que las funciones sean virtuales puras, es decir, perfectamente el código de la clase "superior" (en nuestro caso Empleado) podría tener código
#include<stdio.h>;
#include<conio.h>;
#include<iostream>;
using namespace std;

class figuras {
  public:
  float base;
  float altura;

  public:
  float captura();
  virtual unsigned float perimetro()=0;
  virtual unsigned float area()=0;
};

class rectangulo: public figura{
  public:
  void imprime();
  unsigned float perimetro(){return 2*(base+altura);}
  unsigned float area(){return base*altura;}
};

class triangulo: public figura{
  public:
  void muestra();
  unsigned float perimetro(){2*altura+base}
  unsigned float area(){return (base*altura)/2;}
};

void figura::captura(){
    cout<<"CALCULO DEL AREA Y PERIMETRO DE UN TRIANGULO ISOCELES Y UN RECTANGULO:" <<endl;
    cout<<"escribe la altura: ";
    cin>>altura;
    cout>>"escribe la base: ";
    cin>>base;
};


encapsulamiento-poo
El encapsulamiento en la programación orientada a Objetos ¿Recuerdan que este también es un elemento fundamental del modelo de objetos? sabía que esa era la respuesta, entonces empezaremos con la lección.
Definamos Encapsulamiento:
Es el proceso de almacenar en una misma sección los elementos de una abstracción que constituyen su estructura y su comportamiento; sirve para separar el interfaz contractual de una abstracción y su implantación.
Pero..! ¿Cómo consigo esto?, ¡tranquilo! esto se consigue a través de la ocultación de información, ves como todo es más fácil estando relajado, ¿No sabes que es la ocultación de información?, ¡Tranquilo!, No, aún no estás tranquilo, ¿Ya? seguimos, Ocultación de información es el proceso de ocultar “Todos los Secretos” de un objeto que no aportan a sus características específicas.
Para que la abstracción funcione como debe, la implementación debe estar encapsulada,  nunca está de más recordar que cada clase debe tener dos partes, una interfaz y una implementación, tranquilo no te asustes si no sabes que es una clase, ya llegaremos a ese tema, de momento manténgase concentrado en la encapsulación.

Existen tres niveles de acceso para el encapsulamiento, los cuales son:

Público (Public): Todos pueden acceder a los datos o métodos de una clase que se definen con este nivel, este es el nivel más bajo, esto es lo que tu quieres que la parte externa vea.
Protegido (Protected): Podemos decir que estás no son de acceso público, solamente son accesibles dentro de su clase y por subclases.
Privado (Private): En este nivel se puede declarar miembros accesibles sólo para la propia clase.
Contexto 1:  Se necesita que cualquiera pueda acceder a el color de un vehículo, entonces:
Opción a:  Declaro entonces COLOR como Privado
Opción b:  Declaro entonces COLOR como Protegido
Opción c:   Declaro entonces COLOR Como Público
¡Claro!, Sí escogiste la Opción C, te has Ganado un pase al siguiente ejemplo…, de lo contrario vuelve a darle un repaso a los niveles de acceso.
Contexto 2: Se necesita qué  color se pueda acceder a través no sólo de vehículo, sí no ahora también de Buses,  y como todos sabemos un bus es un tipo de vehículo, entonces también deberá tener acceso a color.
Opción a:  Declaro entonces COLOR como Privado
Opción b:  Declaro entonces COLOR como Protegido
Opción c:   Declaro entonces COLOR Como Público
Correcta Opción b
Contexto 3: Se necesita que color se pueda acceder solamente para vehículo.
Opción a:  Declaro entonces COLOR como Privado
Opción b:  Declaro entonces COLOR como Protegido
Opción c:   Declaro entonces COLOR Como Público
Correcta Opción a
REFERENCIAS:

  • http://laurel.datsi.fi.upm.es/_media/docencia/cursos/cplusplus/cpp_herencia.pdf
  • https://desarrolloweb.com/articulos/polimorfismo-programacion-orientada-objetos-concepto.html
  • https://styde.net/encapsulamiento-en-la-programacion-orientada-a-objetos/
  • https://www.ecured.cu/Polimorfismo_(Inform%C3%A1tica)

Comentarios