Los segundos dos pilares de la programación orientada a objetos
Como mencioné en la primera publicación de esta serie, a menudo escuchará sobre los tres pilares de la programación orientada a objetos. También puede escuchar acerca de Los Cuatro Pilares de la Programación Orientada a Objetos.
Y no es que haya un total de siete ni nada por el estilo. En cambio, se trata más de lo que la gente considera fundamental para la programación orientada a objetos: ¿hay tres o cuatro conceptos principales?
Puede suponer del artículo anterior (y mucho menos el título), creo que hay cuatro.
Y en esta publicación, voy a cubrir los dos últimos:
- Herencia,
- y polimorfismo
Si ha realizado algún tipo de programación orientada a objetos antes de leer este artículo, es probable que haya oído hablar de al menos uno de estos.
De todos modos, echemos un vistazo a cada uno de ellos con más detalle.
Dos pilares más de OOP
Antes de saltar a cada uno de estos, quiero asegurarme de que está al tanto de lo que hemos cubierto hasta ahora.
Una palabra sobre el análisis
No extenderé el punto, pero la razón por la que ahora estoy hablando de los fundamentos de la orientación a objetos es porque estamos pasando a una fase diferente de este material. Comenzamos cubriendo la fase de análisis que incluía:
- Análisis, Parte 1
- Análisis, Parte 2
- Comprender las expectativas del cliente
- Declaración de trabajo
- Términos y condiciones
Ahora al desarrollo
Y ahora estamos en la fase de desarrollo . Algunos pueden llamarlo fundamentos (pero estoy contento de que no se puede hacer un buen desarrollo sin los fundamentos, así que eso es (.
Si no ha leído la publicación anterior, le recomiendo que lo haga antes de continuar, ya que cubre los conceptos de Abstracción, Encapsulación y cómo se relaciona con WordPress.
3 Herencia
El concepto de herencia es bastante fácil de seguir. Es decir, una clase puede heredar atributos de otra clase. Daré algunos ejemplos de esto en un momento, pero permítanme proporcionar una definición de trabajo para los fines de esta publicación:
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.
Ejemplo 1: un documento
En términos muy simples, digamos que tiene una clase llamada Documento y un documento tiene un título y tiene contenido. Luego hay una subclase de documento que tiene atributos para una fecha y hora. Podríamos llamar a esto PostDocument o PageDocument.
Es decir, PageDocument hereda las propiedades y atributos de Document al mismo tiempo que le agrega su propia implementación. ¿Tener sentido?
Si no, no te preocupes. No siempre hace "clic" al principio, así que veamos otro ejemplo.
Ejemplo 2: un mensaje
Digamos que tenemos una clase Message. Un mensaje normalmente tiene dos propiedades:
- 1 un remitente,
- 2 Un destinatario.
Sin embargo, es justo decir que hay diferentes tipos de mensajes, ¿verdad? Es decir, quizás tengamos un EmailMessage o quizás tengamos un TextMessage.
Un EmailMessage todavía tiene un remitente y un destinatario, pero tiene mucho más, ¿verdad? Tiene cosas como:
- una línea de asunto,
- un archivo adjunto opcional,
- otro conjunto de remitentes a los que se envía,
- soporte para copiar a otros en el mensaje de forma pública o privada,
- y mucho más.
Un mensaje de texto, por otro lado, no necesariamente tendrá todo lo anterior. Supongamos que estamos hablando de un mensaje SMS básico (en lugar de un mensaje de texto enriquecido en algo como Hangouts, Telegram, iMessage o cualquier otra cosa que esté disponible).
Esta clase:
- estar vinculado a un número de teléfono,
- puede incluir un grupo de otros destinatarios, todos los cuales son públicos,
- un operador (que es un proveedor de telefonía celular),
- un número máximo de caracteres que puede contener
- la capacidad de dividir un solo mensaje en varios mensajes si la cantidad máxima de caracteres excede una cierta cantidad de caracteres.
Pero aún plantea preguntas sobre las propiedades y los métodos (o, en términos más generales, la implementación, ¿no?)
Una palabra sobre la implementación
Cuando se trata de programación orientada a objetos, tenemos lo que llamamos modificadores de acceso. Tal vez los haya leído en otros lugares denominados, por ejemplo, modificadores de visibilidad o algo así.
Todo es lo mismo.
En resumen, estos modificadores se pueden definir como:
Palabras clave que controlan qué otras clases tienen acceso a la información disponible.
Afortunadamente, esta parte es fácil de entender:
- Las propiedades y funciones privadas solo son accesibles para la clase en la que están definidas. Esto significa que PostDocument no puede usar nada en Documento que esté marcado como privado. Para todos los efectos, PostDocument ni siquiera sabe que existe esta información.
- Las propiedades y funciones protegidas son accesibles para la clase en la que están definidas y cualquier clase que sea descendiente. Es decir, cualquier clase que herede datos de la clase base o de la clase padre tiene acceso a ellos. Entonces, a diferencia de los detalles de implementación privados, PostDocument puede acceder a la información de Document si está marcado como protegido.
- las propiedades y funciones públicas son accesibles a cualquiera. Esto no tiene nada que ver con la herencia, en realidad, sino más bien con la encapsulación, en todo caso. En cambio, se trata de decidir a qué queremos que accedan otros objetos.
Entonces, ¿cómo se maneja la implementación? Esto varía de un idioma a otro, pero PHP no es compatible con lo que se llama "herencia múltiple". En pocas palabras, una clase dada en PHP solo puede heredar (o extender) otra clase. No varias clases (algunos idiomas admiten esto).
Cuando extiende una clase, la subclase hereda todos los métodos públicos y protegidos de la clase principal. A menos que una clase anule esos métodos, conservarán su funcionalidad original.
En nuestro ejemplo, no podemos introducir otra clase como WriteDocument que hereda tanto de PageDocument como de PostDocument. Es uno o el otro. Y vale la pena señalar que si hereda de PostDocument, también hereda información de Document porque es una subclase de una subclase de una clase.
4 polimorfismo
Ahora que tenemos una definición básica de herencia, podemos hablar de polimorfismo. La buena noticia es que es una palabra grande y extraña para un concepto muy simple.
La mala noticia es que no hemos hablado de interfaces o clases abstractas. Estos están llegando, pero se consideran parte de los cuatro pilares, así que no te preocupes por ellos en este momento.
En cambio, piénsalo de la siguiente manera:
El polimorfismo nos permite referirnos a una clase de un tipo cuando puede declararse como de otro tipo.
Todavía puede ser confuso, pero ¿recuerda nuestro ejemplo de mensaje anterior? Podemos instanciar una clase SMSMessage que amplíe la clase Message y luego llamar a ciertos métodos en ella.
El SMSMessage puede tener un método que tiene la clase Message. Y si se ha creado una instancia de la clase como una instancia de la clase SMSMessage, entonces llamará a ese método. De manera similar, si no tiene un método pero su clase principal, Mensaje, sí lo tiene, entonces llamará a ese método.
A veces, es más fácil entender esto en código, así que hagámoslo.
Primero, definamos nuestra clase Message :
<?php
class Message
{
public function send()
{
echo "This message is sent from the Message class.n";
}
public function receive()
{
echo "This message was received from the Message class.n";
}
}
Luego definamos nuestra clase SMSMessage. Tenga en cuenta que no tiene una función de recepción(). Esto será importante momentáneamente:
<?php
class SMSMessage extends Message
{
public function send()
{
echo "This message is sent from the SMSMessage class.n";
}
}
Ahora, instanciamos nuestra clase Message y llamamos a algunos métodos:
<?php
$message = new Message();
$message->send();
$message->receive();
Y hagamos lo mismo usando la clase SMSMessage:
<?php
$message = new SMSMessage();
$message->send();
$message->receive();
Si desea el script completo, puede verlo aquí, descargarlo y ejecutarlo localmente.
Herencia, polimorfismo y WordPress
Esta es la conclusión (y exploraremos esto más cuando nos adentremos en las interfaces y las clases abstractas): cuando una clase extiende otra clase y no tiene los detalles de implementación que tiene su clase principal, se usará la implementación principal.
Otra forma de pensarlo es «trabajar en la cadena de mando". Comenzará con la clase más baja a lo que hemos creado. En nuestro ejemplo anterior, ese es el SMSMessage. Si no lo encuentra allí, subirá a la clase que extiende. (Y si no lo encuentra allí y esa clase extiende una clase, lo intentará allí).
Todo el asunto polimórfico es esto: instanciamos una clase de un tipo, SMSMessage, pero está usando la implementación de una clase de otro tipo (que hereda, sí, pero eso es diferente de todos modos).
Clases de escritura en WordPress
Finalmente, me gustaría dejarlos con esto: he mencionado algo similar a esto en la publicación anterior, pero quiero reiterarlo aquí.
Independientemente de cuántos de estos conceptos utilice el núcleo de WordPress, no importa porque podemos escribir código orientado a objetos de alta calidad en WordPress que interactúa con WordPress y funciona bien con WordPress (y otro código de terceros, no siempre, pero muchas veces).
¿Qué sigue ahora?
A continuación, veremos las interfaces y las abstracciones.
Estos siguen siendo fundamentales para la programación orientada a objetos, pero si ha entendido las dos publicaciones anteriores, está preparado para una experiencia sólida con los próximos conceptos.
Y si no, ¡no te preocupes! Siempre puedes hablar de ello en los comentarios o podemos charlar más sobre ello por correo electrónico.