Ahora que ya entiendes cómo funciona el polimorfismo y lo aplicaste a Java veamos cómo hacer el mismo ejemplo en PHP.
Aplicar polimorfismo en PHP es relativamente más sencillo, pues este es un lenguaje con un tipado más flexible (que no requiere que especifiques qué tipo de dato usar) y su sintaxis es muy sencilla.
Hasta ahora esto es lo que tenemos en nuestro archivo car.php:
<?phprequire_once('account.php');classCar{public$id;public$license;public$driver;protected$passenger;// Es importante que esta propiedad esté marcada como protectedpublicfunction__construct($license,$driver){$this->license=$license;$this->driver=$driver;}publicfunctionprintDataCar(){echo"Licencia: $this->license Driver: ".$this->driver->name;}}?>
Aún nos falta añadir nuestros getters y setters, en PHP es sencillo, simplemente tenemos que escribir dos funciones, una que nos devuelva nuestro número de pasajeros, y otra que nos permita establecer cierto número de pasajeros.
La función getter es la más sencilla de todas, pues simplemente hay que retornar el valor de la propiedad passenger:
Recuerda que para hacer nuestra función setter necesitamos hacer una validación. Uber únicamente nos permite tener 4 pasajeros (comportamiento que modificaremos más adelante con polimorfismo), por lo que nuestra función setter quedaría así:
¡Genial!, ahora ya estamos listos para empezar a trabajar, recuerda que ya deberías tener tu clase UberVan creada hasta este punto 😉.
Antes de comenzar a aplicar polimorfismo veamos qué sucede si intento generar una instancia de 6 pasajeros con mi clase UberVan, recuerda que para hacer estas pruebas estamos trabajando sobre nuestro archivo index.php (no olvides hacer el require hacia el archivo uberVan.php 👀):
Cuando trato de ejecutar este código, esto es lo que me imprime en mi navegador:
Me dice que solo puedo asignar 4 pasajeros, ¡pero para Uber Van deben ser 6 pasajeros! Es hora de usar el polimorfismo.
Aplicando polimorfismo
Para permitir que la clase UberVan acepte 6 pasajeros sin afectar a las otras clases de Uber, necesitamos sobreescribir el método setPassenger, pero permitiendo que esta vez acepte 6 pasajeros.
Recuerda que cuando aplicamos herencia, todos los métodos de la clase Car fueron pasados a la clase UberVan, por tanto, esta clase también tiene acceso al método setPassenger, pero este método solo permite 4 pasajeros. Para aplicar polimorfismo, podemos sobreescribir dicho método dentro de nuestra clase UberVan alojada en el archivo uberVan.php, ¡pero ahora permitiendo 6 pasajeros!
Si lo deseas, también puedes añadir la propiedad $passenger a la clase UberVan (aunque en PHP no es necesario):
protected$passenger;
Para hacerlo más interesante, vamos a cambiar el código de nuestro método printDataCar de la clase Car ubicada en car.php por el siguiente:
publicfunctionprintDataCar(){echo"
Licencia: $this->license Driver: {$this->driver->name} Número de pasajeros: $this->passenger <br>
";}
El código es el mismo, pero lo hicimos más legible, agregamos la información del número de pasajeros y agregamos un salto de línea al final.
¡Ahora pongamos a prueba nuestra clase polimórfica! Vayamos a nuestro index.php, aquí ya teníamos escrito el código para instanciar nuestra clase UberVan con 6 pasajeros, pero agreguemos el código para instanciar una clase de 4 pasajeros:
¡Vualá!, ahora vemos que nuestra clase UberVan nos permite añadir 6 pasajeros, mientras que el resto de clases nos permite seguir añadiendo 4 pasajeros, ¡hemos creado una clase polimórfica!
Reto
Ahora que ya sabes cómo trabajar con polimorfismo en PHP, te reto a que apliques el polimorfismo al método printDataCar de la clase Car en la clase UberX de tal forma que al llamarlo desde una instancia de UberX este también imprima la marca y el modelo.
Una vez que hayas completado el reto puedes dejar tu solución en los aportes de la clase y compararlo con la solución de otros estudiantes. ¡Nos vemos en la siguiente clase para dar un repaso al diagrama UML de Uber que obtuvimos al final!
No es mejor sobreescribir el metodo printDataCar por completo?
excelente codigo, solo le cambiaria en la parte de driver usar el objeto de la clase account para aprovechar el codigo que ya tenemos ahi.
Hacen falta estas clases con python y js
Si una clase se inicia con 4 programas de desarrollo, hay que terminar con 4 programas, así tome tiempo, se que uno puede investigar pero quedamos en las mismas, autodidacta no aplica cuando quieres profesionalismo, debes de tener guía
Aquí mi aporte
Totalmente de acuerdo
Totalmente de acuerdo, con este curso he dado un paso atrás en el aprendizaje.
++Para JavaScript++
Permisos
Los unicos permisos que se puede asignar en JS son publico (default) y privado. Los permisos privados se asignan agregando "#" antes del nombre del atributo. (ej. this.#passenger). Sin embargo no usaremos atributos privados en este ejercicio. Documentación sobre los permisos privados.
.
Getters and Setters
Para referirse a un atributo que debe ser "protegido" la convención es agregar un "_" antes del nombre del atributo (ej. this._passenger). Los getters y setters serían declarados de la siguiente manera.
getpassenger(){returnthis._passenger}setpassenger(passengers){if(passengers !=4){console.log("Debes tener 4 pasajeros")}else{this._passenger= passengers
}
Estos son creados como atributos, no como funciones por lo que la forma correcta de llamarlos sería:
// Forma Correctaconsole.log(this.passsenger)// Llama al getter del atributo ._passengerthis.passenger=4// Llama al setter del atributo ._passenger// Forma incorrectathis.passenger(4)// Devuelve un error ya que no he sido creado como funcionconsole.log(this._passsenger)// Devuelve el valor correcto, pero son malas practicas. El chiste es que uses el getter.this._passenger=-4// Funciona pero son malas practicas y no podrías verificar los valores.
Código completo
Car.js
exportdefaultclassCar{constructor(license, driver){this.idthis.license= license
this.driver= driver
this._passenger}getpassenger(){returnthis._passenger}setpassenger(passengers){if(passengers !=4){console.log("Debes tener 4 pasajeros")}else{this._passenger= passengers
}}printDataCar(){console.group(this.id)console.log('License: '+this.license)console.log('Nombre: '+this.driver.name)console.log('DNI: '+this.driver.document)console.log('Pasajeros: '+this.passenger)console.groupEnd()}}// Para hacerlo con require// module.exports = Car
<?php
require_once('Car.php');classuberXextendsCar{public $brand;public $model;publicfunction__construct($license, $driver, $brand, $model){// siempre es necesario pasarle los parametros a la clase// padre a la clase padreparent::__construct($license,$driver); $this->brand = $brand; $this->model = $model;}publicfunctionprintDataCar(){ echo "
Licencia: $this->license
Driver:{$this->driver->name}Document:{$this->driver->document}Número de pasajeros: $this->passengers
Modelo: $this->model
Marca: $this->brand
<br> ";}}?>
Reusltado:
Solo puedo decir que la sintáxis de PHP es horrible jaja
jajaja es la unica con la que entiendo los temas perfectamente :(
Es costumbre, a la final todo mantiene la misma lógica
Y la Logica de los Modelos Y las Marcas, se debe definir de forma protected ambas y definirle una logica de negocio asi:
<?php
namespace Clases;
class UberX extends Vehiculo{
protected $marca;
protected $modelo;
publicfunction__construct($lic,Cuenta $cuenta,$marca,$modelo){parent::__construct($lic,$cuenta); $this->setMarca($marca); $this->setModelo($modelo);}publicfunctionPrintVehiculo(){$datos=["licencia"=>$this->licencia,"Cedula"=>$this->conductor->documento,"Nombre"=>$this->conductor->nombre,"Pasajeros"=>$this->getPasajeros(),"Marca"=>$this->marca,"Modelo"=>$this->modelo
]; echo json_encode($datos);}publicfunctionsetMarca($marca){ $lista=["HYUNDAI ATOS","CHERY QQ","TAXIS"];if(in_array(upper($marca),$lista)==false){ $this->marca=$marca;}else{ echo "Uber no Acepta esta Marca en su Flota";}}publicfunctionsetModelo($modelo){if((int)($modelo)>=2010){ $this->modelo=$modelo;}else{ echo "Uber no Acepta estos Modelos en su Flota";}}
}
CONSULTA:
Saben porque no me reconoce la variable $licence ? a pesar de que se encuentra dentro de la clase.
Me arroja este error
porque debes acceder con $this
Gracias nicodev 🙌. Justamente eso me faltó
Al parecer no me funciona el código en PHP. La consola retorna lo siguiente:
PHPNotice:Undefined property:UberVan::$license in/home/tms8bltrn/Platzi/POO/Uber/PHP/UberVan.php on line 25PHPNotice:Undefined property:UberVan::$driver in/home/tms8bltrn/Platzi/POO/Uber/PHP/UberVan.php on line 26PHPNotice:Trying to get property 'name'of non-object in/home/tms8bltrn/Platzi/POO/Uber/PHP/UberVan.php on line 26
Lo sorprendente es que con UberPool y UberX sí funciona. ¿Podrían ayudarme, por favor?