¿Qué es el polimorfismo en programación orientada a objetos?
El polimorfismo es una capacidad crucial en la programación orientada a objetos que permite que un único elemento, como un método o una función, se comporte de diferentes maneras. Imagina tener una herramienta multifuncional que, dependiendo de la configuración, puede ofrecer diversos resultados. Este concepto es el corazón de muchos lenguajes de programación, ya que facilita la flexibilidad y la reutilización del código. Por ejemplo, un método get() puede devolver tanto un JSON como un XML, dependiendo de cómo se implemente. Este cambio de comportamiento basado en la función misma es un claro ejemplo de polimorfismo.
¿Cómo se aplica el polimorfismo con clases abstractas e interfaces?
En el mundo de la programación orientada a objetos, el polimorfismo se puede implementar utilizando clases abstractas e interfaces. Las clases abstractas actúan como una plantilla madre para que otras clases hereden y modifiquen comportamientos específicos. Por otro lado, las interfaces definen contratos que las clases deben implementar, forzando el desarrollo de ciertos métodos.
Ejemplo con una clase abstracta
Previo a esta clase, se ejemplificó el polimorfismo mediante una clase abstracta. A continuación, se muestra el enfoque con clases llamadas Admin, User e Invitado que todas comparten un método login, pero que pueden ofrecer resultados diferentes.
abstractclassUsuario{abstractpublicfunctionlogin();}classAdminextendsUsuario{publicfunctionlogin(){return"Login de Admin";}}
Ejemplo con una interfaz
Veamos cómo se puede lograr el polimorfismo con una interfaz, creando una clase User que implementa un método de búsqueda.
interfaceBuscarInterfaz{publicfunctiontodos();}classUserimplementsBuscarInterfaz{publicfunctiontodos(){return"Obteniendo todos los usuarios";}}classPostimplementsBuscarInterfaz{publicfunctiontodos(){return"Obteniendo todos los posts";}}
En este caso, tanto User como Post implementan una interfaz que obliga a definir el método todos(), pero cada uno se comporta de manera diferente.
¿Cuál es la importancia del polimorfismo y su implementación?
El polimorfismo simplifica la programación avanzada permitiendo que el mismo método o función funcione de formas distintas. Este es un concepto fundamental para el uso de interfaces y patrones de diseño. Alprogramar en base a interfaces, se logra una mayor abstracción y flexibilidad, permitiendo que el código funcione a un nivel más general y haciendo posible su reutilización en distintas circunstancias.
Aplicaciones y referencias
Patrones de diseño: Son soluciones estándar para problemas comunes en programación. Usan interfaces para definir cómo deben encontrarse estas soluciones.
Abstracción y modularidad: Hace posible desarrollar código más limpio y fácilmente mantenible evitando la redundancia.
Es esencial practicar y entender este concepto a medida que se progresa hacia temas más avanzados en programación orientada a objetos. Al dominar el polimorfismo, se sientan las bases para entender y aplicar patrones de diseño, lo que resulta invaluable para crear soluciones eficientes sin necesidad de recurrir a lo ya resuelto.
Esto es algo que había comentado en una clase anterior, una interfaz se puede usar para crear diferentes métodos que se comporten de maneras distintas, pero esta sirve como plantilla, y sin querer queriendo ya estamos trabajando usando polimorfismo.
Realmente estas palabras tan "fancys" y "profesionales" son simplemente nombres que le ponemos a las cosas para saber cómo identificarlas, pero al final su definición e implementación es super sencilla, solo hay que quitarse el miedo que estas palabras nos generan
bro la verdad es que estoy re confundido porque no explican el principal proposito de las cosas, las interfaces solo sirven para declarar una funcion A y que las clases que hereden de la interfaz requieran de implmentar en ellas a su vez la funcion A?
pero para que quiero eso si la interface no me deja agregarle comportamiento a la funcion? no entiendo nada, el proposito es?
siento que tiene mas sentido usar una clase ya que en ella puedes agregarle el comportamiento a las funciones y si no defines la funcion dentro de las hijas no da ningun error y puedes seguir usando las funciones de la clase padre libremente y a su vez puedes hacer polimorfismo sobre ella, no entiendo el sentido de las interfaces, es para que tengas que implementar una funcion con un nombre especifico si o si pero, que importa el nombre si puedo poner lo que quiera dentro de esa funcion? aghh
¡Hola!, tienes razón, tal vez hace falta explicar más el propósito de las cosas. No te preocupes, una interfaz es simplemente un contrato, es algo que te asegura que, cualquier clase que implemente esa interfaz sí o sí van a tener los métodos que esa interfaz expone.
A la interfaz no le importa cómo se comporte el método, a la interfaz le importa que cualquier clase que la use, sí o sí tenga ese método.
¿Esto para qué sirve? Bueno, imaginamos que ahora tienes una clase B, y la clase B tiene un método que recibe por parámetro una instancia de cualquier clase. Esto se llama inyección de dependencias y es parte de los principios SOLID y se usa mucho en PHP.
Entonces, como tú esperas que se te pase por parámetro la instancia de una clase, tú puedes simplemente usar esa instancia y acceder a sus métodos:
De esta forma, la clase Saludo tiene un método que recibe una instancia de cualquier otra clase, y este método, sin saber si existe o si no existe el método saludar en esa instancia que se le pasó, lo manda a llamar, y si no existe entonces va a provocar un error.
Aquí es donde las interfaces entran en juego, puedes usar una interfaz para esperar que cualquier clase que se te pase por ahí tenga sí o sí el método que tú quieres, sabes que la interfaz te va a garantizar que ese método sí va a existir cuando se te pase una instancia y que no se te pueda pasar ninguna instancia que no implemente a dicha interfaz:
interfacetienesQueSaludar{publicfunctionsaludar();}classPersonaimplementstienesQueSaludar{/* Ahora está obligado a implementarlo */publicfunctionsaludar(){echo"Hola :D";}}classSaludo{/* Aquí le digo que si la clase no implementa a la interfaz, entonces no puede pasar, así me aseguro que sí o sí puedo usar el método saludar, porque sé que esa interfaz me lo asegura */publicfunctionhacerSaludo(tienesQueSaludar$instancia){$instancia->saludar();}}$saludo=newSaludo();$persona=newPersona();$saludo->hacerSaludo($persona);
Para eso sirven las interfaces, te digo, todo esto hace referencia a los principios SOLID, en este caso se hace especial referencia al principio de inyección de dependencias, te recomiendo tomar el Curso de Buenas Prácticas para Escritura de Código para profundizar en ello :D
Adjunto mi código ya separado de la clase anterior:
<?php
abstract classBase{protected $name;privatefunctiongetClassName(){returnget_called_class();}publicfunctionlogin(){return"Mi nombre es $this->name desde la clase {$this->getClassName()}";}}
<?php
require_once("Base.php");require_once("Admin.php");require_once("User.php");require_once("Guest.php");$guest =newGuest();echo $guest->login();echo('<br>');//Mi nombre es Invitado de la clase guest.$user =newUser('Iridian');echo $user->login();echo('<br>');//Mi nombre es Iridian de la clase user.$admin =newAdmin('Guadalupe');echo $admin->login();echo('<br>');//Mi nombre es Guadalupe de la clase Admin.
No hay necesidad de incluir 'Base.php' en 'index.php' dado que su uso es solo en las clases implementadas.
Ama soim promgramador
#me_da_ansiemdad
Polimorfismo: interfaz
En programación avanzada siempre vamos a trabajar sobre interfaces. Vamos a trabajar con estas porque es lo que enviamos, o sea, que lo enviamos a nivel de configuración.
Nos vamos a encargar de preparar todo el código necesario, así no trabajamos sobre _usuarios _sino sobre la interfaz de usuarios.
<?phprequire_once"./search_interface.php";classUserimplementsSearch{publicfunctionall(){return"Obteniendo a los Usuarios";}}
post.php
<?phprequire_once"./search_interface.php";classPostimplementsSearch{publicfunctionall(){return"Obteniendo a los Post";}}
Por si alguien se pregunta cual es la diferencia entre “extends” e “implements”, es esta (cualquier corrección es bienvenida):
Extends: Se utiliza cuando trabajamos con clases y permite extender (heredar) las propiedades y el comportamiento de una clase existente (padre) a una subclase (hija).
Implements: Se utiliza al trabajar con interfaces y permite (y se debe) implementar todos los métodos definidos en la interfaz, dentro de la clase donde se esta implementando
En una interfaz, todos los métodos son abstractos. Osea, el código de cada método se define en la clase que implementa la interfaz.
si, entendí esa parte pero, el propósito de esto es?
El propósito de las interfaces es crear "contratos"; métodos que obligatoriamente debe implementar (contener) una Clase (aunque no tienen por qué comportarse del mismo modo).
En polimorfismo un método puede tener distintas implementaciones y soluciones. ¿Cómo influye al momento de realizar los test? El uso de los tests nos sugiere que un método tienen que tener un único resultado
¡Hola!, no entiendo a qué te refieres con lo de "uso de los tests", ¿te refieres al Test Driven Development? Para este caso tú programas el resultado esperado, es por eso que a hacer polimorfismo debes asegurarte que no se rompa nada, además, al hacer polimorfismo lo haces en una clase aparte, así que eso no debería afectar a tus tests de la clase original.
Ya con esta clase quedo mucho más claro como es que funcionan las interfaces ya que cuando las vimos de forma muy rápida hace unas clases la verdad me quede con la idea principal pero no entendía la implementación de estas....
Comparto mi código con el resultado comentado.
.
BaseInterface
<?php// Creando la interfaz 'BaseInterface'interfaceBaseInterface{// Creando método necesario para las clases que implementen está interfazpublicfunctionall();}?>
.
User
<?php// Incluyendo el archivo de 'BaseInterface'include_once("BaseInterface.php");// Creando clase que implementa la Interfaz 'BaseInterface'classUserimplementsBaseInterface{/*
Como la interfaz de la cual se implementa esta clase tiene 1 método,
se debe cumplir el contrato e implementar dicho método en esta clase si no arroja el siguiente error:
Fatal error: Class User contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (BaseInterface::all)
*/// Implementando el método de la interfazpublicfunctionall(){return'Obteniendo a todos los Usuarios';}}// Instanciando un objeto de la clase 'User'$user1=newUser();echo$user1->all();// Obteniendo a todos los Usuarios?>
.
Post
<?php// Incluyendo el archivo de 'BaseInterface'include_once("BaseInterface.php");// Creando la clase 'Post' que implementa la interface 'BaseInterface'classPostimplementsBaseInterface{// Creando el método necesario que se declaro en la Interfazpublicfunctionall(){return"Obteniendo todos los POST";}}// Instanciando un objeto de la clase 'Post'$post1=newPost();echo$post1->all();// Obteniendo todos los POST?>
Adjunto mi código que vimos en la clase acerca de la interfaz:
<?php
require_once("SearchInterface.php");classPostimplementsSearch{//aquí desarrollamospublicfunctionall(){return"Obteniendo a los Users aunque también puedo obtener un xml <br/>";}}
SearchInterface.php
<?php
interfaceSearch{//declaramos un unico método para que funcione para el restopublicfunctionall();}
User.php
<?php
require_once("SearchInterface.php");classUserimplementsSearch{//aquí desarrollamospublicfunctionall(){return"Obteniendo a los Users aunque también puedo obtener un json <br/>";}}
El polimorfismo en programación orientada a objetos (POO) en PHP permite que diferentes clases respondan a la misma llamada a un método de manera única. Esto significa que puedes utilizar un solo método en diferentes contextos, proporcionando resultados distintos según la clase que lo implemente. Hay dos formas comunes de lograr polimorfismo: mediante herencia y mediante interfaces. Al usar interfaces, como en el ejemplo de usuarios y posts, garantizas que todas las clases que implementan la interfaz deben definir el método correspondiente, permitiendo comportamientos variados pero coherentes en toda la aplicación.
Un cordial saludo
¿Cuál es la diferencia si creo una class User y una Post sin implementar una interfaz y ambas clases tienen el método all()?
¿También funcionaría no?
¿Dónde radica la diferencia?
Gracias
La diferencia esta en que no estas modulando, evidentemente con un codigo sencillo como el planteado no se nota la diferencia. Pero cuando hay varios metodos, mas clases, etc, la modularidad aplica.
<?php
require_once "./Base.php";
require_once "./Admin.php";
require_once "./User.php";
require_once "./Guest.php";
$guest = new Guest();
echo $guest->login()."<br>";
$user = new User('Samir');
echo $user->login() ."<br>";
$admin = new Admin('Carlos');
echo $admin->login();
¿Te sale error ese código?
No creo que esté siendo muy buen curso, habría que reestructurarlo
Creo que estos cursos de POO tendrian mas sentido si fueran con proyectos reales no con superheroes, michis o palabras sueltas. Algo que permita afianzar y aprender de forma mas profunda. El instructor es muy bueno se nota, como muchos en Platzi pero precisamente encuentro un poco complejo aprender con temas sin secuencia o relacion.
Una clase es como un plano para construir un objeto, mientras que una interfaz es como un contrato que define qué métodos debe implementar una clase.
Clase:
Una clase en PHP es un molde para crear objetos. Contiene propiedades y métodos que definen el comportamiento y las características de esos objetos.
Dentro de una clase, puedes definir propiedades (variables) y métodos (funciones) que representan el estado y el comportamiento del objeto.
Puedes crear múltiples instancias u objetos basados en una misma clase, y cada objeto tendrá su propio conjunto de valores de propiedades.
Ejemplo:
classCoche{public$marca;public$modelo;publicfunctionencender(){echo"El coche está encendido.";}publicfunctionapagar(){echo"El coche está apagado.";}}
Interfaz:
Una interfaz en PHP define un conjunto de métodos que una clase debe implementar. Es como un contrato que asegura que cualquier clase que implemente esa interfaz proporcionará la funcionalidad especificada.
Las interfaces son útiles cuando deseas establecer un comportamiento común entre diferentes clases que no necesariamente tienen una relación de herencia común.
No puedes definir propiedades dentro de una interfaz, solo métodos.
Una clase que implemente esta interfaz debe proporcionar implementaciones concretas para los métodos acelerar() y frenar(). Por ejemplo:
classCocheDeportivoimplementsConduccion{publicfunctionacelerar(){echo"El coche deportivo está acelerando.";}publicfunctionfrenar(){echo"El coche deportivo está frenando.";}}
Una clase es un plano para crear objetos que encapsulan estado y comportamiento, mientras que una interfaz es un contrato que define qué métodos debe proporcionar una clase. Las clases pueden implementar múltiples interfaces pero solo pueden heredar de una sola clase (en PHP).
<?php
require('Admin.php');require('User.php');require('Guest.php');abstract classBase{protected $name;privatefunctiongetClassName(){returnget_called_class();}publicfunctionlogin(){return"Mi nombre es {$this -> name} desde la clase {$this -> getClassName()}";}}$guest =newGuest();echo $guest ->login();echo '<br>';$user =newUser('Diego');echo $user ->login();echo '<br>';$user =newUser('Isaac');echo $user ->login();
<?php
abstract classBase{protected $name;privatefunctiongetClassName(){returnget_called_class();}publicfunctionlogin(){return"Mi nombre es $this->name desde la clase {$this->getClassName()}";}}
En este caso como estamos modularizando todos los archivos al mismo index no se debe llamar en cada documento por separado, simplemente se llama primero que toso los demas documentos ya que estos depende de "Base.php".