Rimorsoft Online
Blog Foro

Características de la OOP (Polimorfismo y Herencia)


Los conceptos de la programación orientada a objetos siempre serán importantes, aquí nos enfocamos en el polimorfirmo y la herencia, esto complementa bastante bien la publicación Conceptos de Programación Orientada a Objetos. Todo esto va sumando y estoy seguro de que pronto dominarás cada uno de estos terminos.

Polimorfismo

Este tema podría no ser difícil, vamos a tratarlo con un par de ejemplos bastantes claros para lograr comprenderlo con éxito. La palabra polimorfismo tiene como definición "varias formas" y en programación orientada a objetos puede aplicarse de varias maneras.

Con varias formas quiero decir que un método al interactuar con diferentes objetos tendrá diferentes comportamiento o diferentes resultados.

Ejemplo con clase abstracta

Tenemos una clase madre y algunas clases hijas. La idea es demostrar como cada hija usando el mismo método de su clase madre obtendrá un resultado diferente.

Básicamente un método podrá tener diferentes resultados, al ser esto posible hablamos de polimorfismo.

Vamos a trabajar con los siguientes archivos:

  • Base.php: Clase madre.
  • Admin.php: Clase hija de Base.
  • User.php: Clase hija de Base.
  • Guest.php: Clase hija de Base.
  • index.php: Desde aquí ejecutaremos nuestro proyecto.

Clase abstracta Base.php

<?php

abstract class Base
{ 
    protected $name = ''; 

    private function className()
    {
    	return get_called_class();
    }

    public function login(){ 
        return "
		    Mi nombre es {$this->name}: 
			desde la clase {$this->className()} 
			y me encuentro iniciando sesion... <br>
	    "; 
    }
} 

Tengo a la propiedad $name y el método login() que aprovecharemos desde las clases hijas. Toma en cuenta el concepto de "un método, varios resultados".

Clase hija Admin.php

<?php

class Admin extends Base
{ 
    public function __construct($name)
    {
    	$this->name = $name;
    }
} 

Solo damos de alta el nombre del administrador a través de un constructor.

Clase hija User.php

<?php

class User extends Base
{ 
    public function __construct($name)
    {
    	$this->name = $name;
    }
} 

Mantenemos la misma estructura lógica que con Admin.php. Ambas dicen claramente que pueden dar de alta su nombre en la propiedad definida en la clase abstracta.

Clase hija Guest.php

<?php

class Guest extends Base
{ 
	protected $name = 'Invitado';
} 

Esta sería la clase usada para permitir el paso a usuarios invitados, toma en cuenta que damos de alta a un nombre por defecto que en este caso es "Invitado".

Las tres clases pueden por supuesto usar el método login().

Usemos todo esto en nuestro index.php.

Archivo index.php

<?php 

require_once('Base.php');

require_once('User.php');
require_once('Admin.php');
require_once('Guest.php');

$guest = new Guest(); 
echo $guest->login(); 

$user = new User('Italo Morales'); 
echo $user->login(); 

$admin = new Admin('Lynda Morales'); 
echo $admin->login(); 

// Al ejecutar este código tendremos en pantalla el siguiente mensaje

// Mi nombre es Invitado: 
// desde la clase Guest y me encuentro iniciando sesion...

// Mi nombre es Italo Morales: 
// desde la clase User y me encuentro iniciando sesion...

// Mi nombre es Lynda Morales: 
// desde la clase Admin y me encuentro iniciando sesion... 

Y aquí vemos claramente el concepto...

  • Cada mensaje me dice el nombre de la clase de donde nos conectamos gracias a get_called_class().
  • Los mensajes son diferentes.
  • Veo en cada mensaje al nombre del usuario conectado.
  • Y lo mas importante, en todos los casos uso el método login() y la propiedad $name.

Ejemplo con interfaz

  • Una única interfaz.
  • Varias clases implementan esta interfaz.
  • Cada clase usa y desarrolla como quiera a cada método.

Usar una interfaz, es decir, crearla da como resultado el principio de polimorfismo. Es un recurso válido a la hora de implementar polimorfismo.

¿Qué es una interfaz?: Es un archivo que tiene dentro métodos públicos y de esa manera la clase que la implemente se encargará de desarrollar cada método. Sus características son las siguiente:

  1. La interfaz solo declara los métodos.
  2. Todos los métodos deben ser públicos.
  3. Una interfaz no contiene atributo alguno.
  4. Los métodos allí definidos de desarrollan en la clase que la implemente.
  5. La clase está obligada a usar la estructura definida en la interfaz.
  6. Es posible que una clase implemente varias interfaces.
  7. Una interfaz no se puede instanciar.

¿Aplica el concepto?: De hecho si, porque cada clase que implemente a una interfaz tendrá dentro de si los mismos métodos pero no necesariamente el mismo comportamiento ni el mismo resultado.

Interfaz Search.php

<?php

interface Search 
{
	public function all();
}

Tiene lo necesario, un método público y nada mas.

Clase User.php

<?php

class User implements Search
{ 
    public function all()
    {
    	return "Obteniendo todos los usuarios... <br>";
    }
} 

Tenemos una clase que implementa la interfaz y al hacerlo nos obliga a desarrollar el método all().

Clase Post.php

<?php

class Post implements Search
{ 
    public function all()
    {
    	return "Obteniendo todos los posts... <br>";
    }
} 

Archivo index.php

<?php 

require_once('Search.php');

require_once('User.php');
require_once('Post.php');

$user = new User(); 
echo $user->all();

$post = new Post(); 
echo $post->all();

## Al ejecutar, vemos el siguiente resultado. ##

// Obteniendo todos los usuarios...
// Obteniendo todos los posts... 

Resumen

Cuando hablamos de polimorfismo nos referimos a una capacidad o virtud que tienen los métodos, donde por ejemplo un mismo método puede tener diferentes comportamientos y dar diferentes resultados.

El concepto de polimorfismo trata precisamente de que una misma cosa termina comportándose de diferentes maneras. Aquí hemos visto ejemplos con PHP, toma en cuenta que otros lenguajes podrían tener diferentes método o maneras de implementación. Es probable que en otros lenguajes se logre de igual forma o aplicando una jerarquía de clases y nada mas.

Diferencia entre interfaces y clases abstractas

Esto requiere un post entero, pero te puedo adelantar lo siguiente:

En una interfaz definimos métodos sin códigos, en clase abstracta puede definir métodos y desarrollarlos. Lo interesante es crear una clase abstracta y hacer que esta clase implemente una interfaz. Una interfaz provee los métodos a implementar y una clase abstracta proporciona en la mayoría de los casos una funcionalidad base o por defecto.

Es importante dedicarle un poco mas a este tema en particular, los patrones de diseño proporcionan en estos casos responsabilidades y organización que nos ayuda a entender bien cada rol. Cuando profundicemos en esta área comprenderás realmente cuando usar cada cosa.

Herencia

Esto es probable que lo hayas escuchado como jerarquía, ese termino también es válido. Podemos heredar una clase o podemos relacionar objetos. En ambos casos significa herencia y si detallamos en características observamos lo siguiente:

  • Clase 1: Tengo 5 métodos.
  • Clase 2: Tengo 4 métodos.
  • Si la Clase 2 hereda de la Clase 1 podré disponer de 9 métodos.

Básicamente es: Usaré mis métodos más los métodos heredados.

En los ejercicios realizados en los capítulos anteriores vemos cómo heredamos de una clase abstracta. ¿eso es herencia?. La respuesta es SI.

Más abajo encontrarás mayor detalle práctico, toma en cuenta que aquí hablamos del principio de la herencia como principio de desarrollo o de programación orientada a objetos. Veamos a continuación el ejemplo:

Clase User.php

<?php

class User 
{
    public $name;

    public function __construct($name)
    {
        $this->name = $name;
    }

    public function getName()
    {
        return $this->name;
    }
}

Esta sería mi clase principal, quiero que Admin.php herede de User.php. Suena lógico cuando pensamos que los administradores son usuarios también.

Clase Admin.php

<?php

class Admin extends User
{ 
    //...
} 

Aquí no desarrollamos ningún método, quiero simplemente usar los métodos desarrollados en User.php.

Archivo index.php

<?php 

require_once('User.php');
require_once('Admin.php'); 

$admin = new Admin('Italo Morales'); 
echo $admin->getName();
// Al ejecutar tenemos el siguiente resultado: Italo Morales

Esto es nuestro día a día, en Laravel podemos ver como nuestra entidad User extiende de Authenticatable y así muchos ejemplos, esto dice claramente que desde la entidad de usuarios podré usar todos los métodos desarrollados en Authenticatable.

Podemos por supuesto crear la jerarquía necesaria, no hay límites al respecto. Básicamente es posible crear una escalera de clases sin ningún problema.

También es posible manejar la herencia relacionando objetos, imagina los siguientes casos.

  1. Tengo una clase que dentro de sus métodos requiere instanciar otro objeto y usar sus métodos, esto sería herencia o relación directa.
  2. Tengo dos objetos y paso un objeto por parámetro para que a partir de allí pueda usar sus métodos.

Hay muchas formas de usar métodos o funciones heredadas, en cualquier caso estarías aplicando este principio de programación orientada a objetos en tus proyectos.

Resumen: Características de la OOP

Esto no tiene porque ser complejo. Cuando creas una clase solo debes tener en cuenta que cumplas con lo siguiente:

  1. Herencia: Básicamente usaré mis métodos más los heredados.
  2. Abstracción: Es aislar, separar y sacar... Si llevamos a un papel alguna solicitud de este tipo podríamos pensar en lo común y no en el detalle.
  3. Polimorfismo: Capacidad o virtud que tienen los métodos, donde por ejemplo un mismo método puede tener diferentes comportamientos y dar diferentes resultados..
  4. Modularidad: Este principio básicamente nos ayuda a tener cada vez piezas de código mas pequeñas y entendibles, donde cada pieza es un módulo.
  5. Encapsulamiento: Un objeto debe estar aislado y ser un módulo natural. Esto se cumple aplicando la protección a las propiedades impidiendo su modificación y básicamente controlar el acceso según nuestro criterio.

Cada concepto te ayudará a desarrollarte mejor en este valioso mundo, esto que has estudiado trata sobre los principios de la programación orientada a objetos y vemos por supuesto ejemplos con PHP.

Es importante recordar lo comentado anteriormente:

  • Programación orientada a objetos: Es la técnica o principio de desarrollo.
  • PHP: Hace referencia al lenguaje de programación.

El primero te habla sobre su importancia y detalla profesionalmente su uso, y el segundo detalla la implementación.

En muchos videos y posts aquí en rimorsoft he descrito la estructura de una clase y cómo esta se puede convertir en un objeto, eso esta bien y nos ayuda a avanzar en gran medida. Aquí tenemos los conceptos y dominar este tema definitivamente da un plus profesional.

Hay mas detalles al respecto como por ejemplo patrones de diseño.

Patrones de diseño

Esto trata sobre problemas que ya han sido resueltos, son estándares, soluciones comunes para resolver problemas comunes o problemas ya conocidos. La idea es saber que esto existe y reutilizarlo en nuestros proyectos.

Sigue conectado a Rimorsoft Online, estudiaremos todo al respecto.

¡Que sigas estando bien!...

Libro de TDD - Lo que debes saber
Compra el libro
TDD lo que debes saber

Newsletter

Únete a más de 4.000+ personas y no te pierdas nunca más de las nuevas clases, tips, tutoriales y más cada semana.

    No enviamos spam. Puedes darte de baja en cualquier momento.