Mirando el polimorfismo en profundidad
Cuando comencé esta serie, hablé sobre los cuatro pilares de la programación orientada a objetos. Cada uno de estos temas se enumeran y vinculan a continuación.
En este punto, normalmente me gustaría comenzar a pasar al siguiente tema. Sin embargo, antes de hacerlo, me gustaría pasar una publicación más explorando el concepto de polimorfismo.
En mi carrera, hasta ahora, he visto pocos temas que les den a quienes se inician en la programación orientada a objetos más confusión y problemas que el polimorfismo. Así que me gustaría discutirlo un poco más en profundidad dentro del contexto de la programación orientada a objetos y fuera de cualquier marco o aplicación en particular (como WordPress).
En esta publicación, haré una revisión rápida de lo que hemos discutido hasta ahora, luego volveré al polimorfismo.
Polimorfismo en profundidad
Primero, como se mencionó, quiero revisar rápidamente lo que se ha discutido hasta ahora, especialmente si ha pasado por alto alguna de las publicaciones anteriores.
No se preocupe: nada a continuación se desvía del código. En cambio, simplemente define los términos que hemos usado para que tenga una idea de a qué me refiero cada vez que vea la palabra surgir a lo largo de esta serie.
Abstracción
Abstraemos la idea de algo en una clase. En cambio, vamos a abstraer ideas en sus clases. Y aquí hay una idea clave: una clase debe representar un sustantivo.
Encapsulación
La encapsulación es realmente solo una palabra "grande" que se refiere a la idea de administrar sus responsabilidades (o realizar un seguimiento de sus datos).
Herencia
La herencia se refiere a la idea de que una clase, aunque tiene su propia implementación, literalmente hereda propiedades, funciones e implementación general de una clase principal.
Polimorfismo
El polimorfismo nos permite referirnos a una clase de un tipo cuando puede declararse como de otro tipo.
Dicho esto, aquí es donde creo que las cosas pueden complicarse un poco más. En las publicaciones anteriores, proporcioné una serie de ejemplos de código diferentes (y le insto a que los revise).
Pero en la publicación de hoy, voy a tratar de explorar la idea un poco más, tanto en la explicación como en el código.
Relativo a la herencia
Si no es evidente en este punto, el polimorfismo está muy relacionado con la herencia. Piénselo de esta manera: si una clase hereda propiedades y métodos de otra clase, entonces puede "reemplazar" a la clase principal.
Eso significa que si tiene algo como una clase de contenido y luego tiene dos subclases, una es una publicación y otra es una página, puede crear una instancia de la clase utilizando el tipo de referencia de contenido .
Pero en tiempo de ejecución, en realidad será una instancia del tipo Post. ¿Tener sentido? Aquí hay un código como ejemplo.
Primero, comenzaremos con la definición de una clase de contenido :
<?php
class Content {
protected $title;
protected $content;
protected $metadata;
public function __construct()
{
$this->title = "Hello World!";
$this->content = "This is a sample piece of content.";
$this->metadata = "<This is the metadata of the post.>";
}
public function getTitle()
{
return $this->title;
}
public function getContent()
{
return $this->content;
}
public function getMetadata()
{
return $this->metadata;
}
}
Tiene las propiedades generales que probablemente espera: título, contenido y metadatos. Por supuesto, estas propiedades son solo cadenas, pero podrían ser estructuras de datos más elaboradas en una situación del mundo real.
Ahora veamos una publicación :
<?php
class Post extends Content {
private $author;
public function __construct() {
parent::__construct();
$this->author = "Tom McFarlin";
}
public function getAuthor()
{
return $this->author;
}
}
Entonces, ¿qué sucede si llama a un método en la clase Post, como getTitle, que no existe pero existe en la clase Content? Luego, debido a la herencia, buscará el método en Post, no lo encontrará, luego comenzará a buscarlo en Content.
Si lo encuentra, lo ejecutará.
Del mismo modo, podemos hacer algo como esto con la clase de página y los datos de contenido. Primero, instanciamos la clase base y luego establecemos las propiedades específicas de la página. En este caso, va a ser una categoría.
<?php
class Page extends Content {
private $category;
public function __construct() {
parent::__construct();
$this->category = "Articles";
}
public function getCategory()
{
return $this->category;
}
}
Ahora, cuando ejecutamos el código, podemos comenzar con el Contenido:
<?php
$content = new Content();
echo $content->getTitle();
Tenga en cuenta que esto parece lo que esperaríamos, ya que tenemos un título y tenemos contenido. Veamos también el Post :
<?php
// These will work because they reside in the Content base class.
$post = new Post();
echo $post->getAuthor();
echo $post->getTitle();
Esto funciona porque tenemos un autor pero también tenemos un título porque reside en Contenido. ¿Pero si tratamos de llamar a getAuthor en una instancia de Post?
<?php
// These will work because they reside in the Content base class.
$post = new Post();
echo $post->getAuthor();
echo $post->getTitle();
Vamos a recibir un error porque el método no reside en esa clase.
Entonces, ¿qué vamos a hacer? Dado que no tenemos tipos fuertes en PHP, no podemos convertirlo en un tipo diferente.
Hay patrones de diseño para esto, que discutiré en un futuro conjunto de publicaciones, pero PHP no lo permite tan fácilmente como otros lenguajes (como C# o Java).
Preguntas sobre el polimorfismo
Con suerte, el código anterior le dará una idea de cómo un tipo concreto, como una publicación o una página, puede tener implícitamente las propiedades y los métodos de su clase base, Content, que se usan en tiempo de ejecución.
Pero también plantea algunas preguntas, ¿no? Por ejemplo:
- ¿Por qué es útil el polimorfismo? En última instancia, es una cuestión de flexibilidad. Es decir, puede escribir un tipo de Contenido genérico y luego crear una Publicación o una Página como hemos visto anteriormente. Esto nos brinda todos los beneficios de la clase Content y también nos brinda la especificidad de la clase Post, por ejemplo.
- Esto parece ser más confuso que flexible. En cierto modo, es confuso porque el código requiere un poco de seguimiento. Es decir, puede comenzar en la clase Publicar y tener que buscar lo que ofrece la clase Contenido . Por otro lado, también hace que sea muy fácil introducir una nueva subclase de contenido y luego usarla cuando sea más adecuada en tiempo de ejecución.
En lo que respecta a las superclases y subclases, aquí es donde entra en juego tener un IDE sólido.
Siempre es bueno tener un editor que te guste, claro, pero tener uno que pueda determinar intuitivamente cuál es la clase principal, cuál es la clase base, etc., puede ser de gran ayuda para rastrear, depurar, seguir y escribir nuevos código.
Pero eso es contenido para otra publicación que vendrá después de que hablemos sobre patrones de diseño.

