informatica:programacion:programacion_orientada_a_objetos:php
Diferencias
Muestra las diferencias entre dos versiones de la página.
| Ambos lados, revisión anteriorRevisión previaPróxima revisión | Revisión previa | ||
| informatica:programacion:programacion_orientada_a_objetos:php [2023/03/17 10:13] – [Evitar sobrescritura] tempwin | informatica:programacion:programacion_orientada_a_objetos:php [2023/03/22 10:13] (actual) – [Traits (rasgos)] tempwin | ||
|---|---|---|---|
| Línea 211: | Línea 211: | ||
| </ | </ | ||
| + | La ventaja de usar '' | ||
| ===== Herencia ===== | ===== Herencia ===== | ||
| Línea 432: | Línea 433: | ||
| $fulanito-> | $fulanito-> | ||
| $fulanito-> | $fulanito-> | ||
| + | </ | ||
| + | |||
| + | ==== Conversión de una clase a cadena (__toString) ==== | ||
| + | |||
| + | Por medio de la función '' | ||
| + | |||
| + | <code php> | ||
| + | class Gato { | ||
| + | |||
| + | private $nombre; | ||
| + | private $pelo; | ||
| + | | ||
| + | public function __construct($nombre, | ||
| + | | ||
| + | $this-> | ||
| + | $this-> | ||
| + | } | ||
| + | | ||
| + | public function __toString() { | ||
| + | return "Mi nombre es " . $this-> | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | <code php> | ||
| + | $benito = new Gato(" | ||
| + | |||
| + | echo $benito; // Mostrará "Mi nombre es benito y el color de mi pelo es azul" | ||
| </ | </ | ||
| ===== Métodos y propiedades estáticas ===== | ===== Métodos y propiedades estáticas ===== | ||
| Línea 767: | Línea 796: | ||
| </ | </ | ||
| - | ==== Carga automática | + | ==== Carga automática |
| Al crear un fichero por clase, cuando vamos a usar muchas, una de las mayores molestias es tener que hacer una larga lista de inclusiones al comienzo de cada script (uno por cada clase). A partir de la versión 5.0.0 de PHP se pueden hacer autocargas para evitar el uso de '' | Al crear un fichero por clase, cuando vamos a usar muchas, una de las mayores molestias es tener que hacer una larga lista de inclusiones al comienzo de cada script (uno por cada clase). A partir de la versión 5.0.0 de PHP se pueden hacer autocargas para evitar el uso de '' | ||
| Línea 846: | Línea 875: | ||
| <WRAP center round info 60%> | <WRAP center round info 60%> | ||
| - | Las interfaces | + | Las interfaces en proyectos |
| </ | </ | ||
| Línea 859: | Línea 888: | ||
| </ | </ | ||
| - | Implementamos un par de clases: | + | Implementamos un par de clases |
| <code php> | <code php> | ||
| Línea 952: | Línea 981: | ||
| Porque solo la propiedad '' | Porque solo la propiedad '' | ||
| + | |||
| + | ===== Comparación de objetos ===== | ||
| + | |||
| + | Dos instancias de una clase son iguales si tienen los mismos atributos y valores (los valores se comparan con el operador de igualdad, '' | ||
| + | |||
| + | Cuando se utiliza el operador de identidad ('' | ||
| + | |||
| + | <code php> | ||
| + | class Gato { | ||
| + | |||
| + | public $bandera; | ||
| + | } | ||
| + | |||
| + | class Perro { | ||
| + | |||
| + | public $bandera; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Comparamos: | ||
| + | |||
| + | <code php> | ||
| + | $gato1 = new Gato(); | ||
| + | $gato2 = new Gato(); | ||
| + | $gato3 = $gato1; // copia por referencia | ||
| + | |||
| + | $perro1 = new Perro(); | ||
| + | |||
| + | echo " | ||
| + | |||
| + | echo "gato1 == gato"; | ||
| + | echo ($gato1 == $gato2) ? " Verdadero" | ||
| + | |||
| + | |||
| + | echo "gato1 != gato"; | ||
| + | echo ($gato1 != $gato2) ? " Verdadero" | ||
| + | |||
| + | |||
| + | echo "gato1 === gato"; | ||
| + | echo ($gato1 === $gato2) ? " Verdadero" | ||
| + | |||
| + | |||
| + | echo "gato1 !== gato"; | ||
| + | echo ($gato1 !== $gato2) ? " Verdadero" | ||
| + | </ | ||
| + | |||
| + | Resultado: | ||
| + | |||
| + | < | ||
| + | Comparamos elementos de la misma clase | ||
| + | gato1 == gato Verdadero | ||
| + | gato1 != gato Falso | ||
| + | gato1 === gato Falso | ||
| + | gato1 !== gato Verdadero | ||
| + | </ | ||
| + | |||
| + | Compararemos elementos de la misma clase a la misma referencia: | ||
| + | |||
| + | <code php> | ||
| + | echo " | ||
| + | |||
| + | echo "gato1 == gato3"; | ||
| + | echo ($gato1 == $gato3) ? " Verdadero" | ||
| + | |||
| + | |||
| + | echo "gato1 != gato3"; | ||
| + | echo ($gato1 != $gato3) ? " Verdadero" | ||
| + | |||
| + | |||
| + | echo "gato1 === gato3"; | ||
| + | echo ($gato1 === $gato3) ? " Verdadero" | ||
| + | |||
| + | |||
| + | echo "gato1 !== gato3"; | ||
| + | echo ($gato1 !== $gato3) ? " Verdadero" | ||
| + | </ | ||
| + | |||
| + | Resultado: | ||
| + | |||
| + | < | ||
| + | Compararemos elementos de la misma clase a la misma referencia: | ||
| + | gato1 == gato3 Verdadero | ||
| + | gato1 != gato3 Falso | ||
| + | gato1 === gato3 Verdadero | ||
| + | gato1 !== gato3 Falso | ||
| + | </ | ||
| + | |||
| + | Finalmente, compararemos elementos de diferente clase (aunque tengan los mismos elementos): | ||
| + | |||
| + | <code php> | ||
| + | echo " | ||
| + | |||
| + | echo "gato1 == perro1"; | ||
| + | echo ($gato1 == $perro1) ? " Verdadero" | ||
| + | |||
| + | echo "gato1 != perro1"; | ||
| + | echo ($gato1 != $perro1) ? " Verdadero" | ||
| + | |||
| + | echo "gato1 === perro1"; | ||
| + | echo ($gato1 === $perro1) ? " Verdadero" | ||
| + | |||
| + | echo "gato1 !== perro1"; | ||
| + | echo ($gato1 !== $perro1) ? " Verdadero" | ||
| + | </ | ||
| + | |||
| + | Resultado: | ||
| + | |||
| + | < | ||
| + | Compararemos elementos de la misma clase a la misma referencia: | ||
| + | gato1 == perro1 Falso | ||
| + | gato1 != perro1 Verdadero | ||
| + | gato1 === perro1 Falso | ||
| + | gato1 !== perro1 Verdadero | ||
| + | </ | ||
| ===== Clases anónimas ===== | ===== Clases anónimas ===== | ||
| + | |||
| + | Las clases anónimas no tienen nombre. Disponibles desde la versión 7 de PHP. | ||
| + | |||
| + | Las clases anónimas son útiles para definir objetos sencillos y desechables. | ||
| + | |||
| + | <code php> | ||
| + | $gato = new Class(" | ||
| + | private $nombre; | ||
| + | | ||
| + | public function __construct($nombre) { | ||
| + | $this-> | ||
| + | } | ||
| + | | ||
| + | public function getNombre() { | ||
| + | return "Mi nombre es " . $this-> | ||
| + | } | ||
| + | }; | ||
| + | |||
| + | echo $gato-> | ||
| + | </ | ||
| + | |||
| + | ===== Traits (rasgos) ===== | ||
| + | |||
| + | Por medio de los // | ||
| + | |||
| + | Podemos reutilizar código (conjuntos de métodos) sobre clases independientes o a jerarquía de clase diferentes. | ||
| + | |||
| + | Un rasgo o trait es similar a las clases, pero solo agrupa métodos específicos. | ||
| + | |||
| + | <code php> | ||
| + | interface Animal { | ||
| + | function nacer(); | ||
| + | function crecer(); | ||
| + | function reproducir(); | ||
| + | function morir(); | ||
| + | } | ||
| + | |||
| + | abstract class Vertebrado implements Animal { | ||
| + | private $huesos; | ||
| + | | ||
| + | public function getHuesos() { | ||
| + | return $this-> | ||
| + | } | ||
| + | | ||
| + | public function nacer() {}; | ||
| + | public function crecer() {}; | ||
| + | public function reproducir() {}; | ||
| + | public function morir() {}; | ||
| + | } | ||
| + | |||
| + | abstract class Invertebrado implements Animal { | ||
| + | private $hemocianina; | ||
| + | | ||
| + | public function getHemocianina() { | ||
| + | return $this-> | ||
| + | } | ||
| + | | ||
| + | public function nacer() {}; | ||
| + | public function crecer() {}; | ||
| + | public function reproducir() {}; | ||
| + | public function morir() {}; | ||
| + | } | ||
| + | |||
| + | class Molusco extends Invertebrado { | ||
| + | |||
| + | private $radula; | ||
| + | | ||
| + | public function getRadula() { | ||
| + | return $this-> | ||
| + | } | ||
| + | } | ||
| + | |||
| + | class Reptil extends Invertebrado { | ||
| + | |||
| + | private $escamas; | ||
| + | | ||
| + | public function getEscamas() { | ||
| + | return $this-> | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Tanto los moluscos como los reptiles son ovíparos. Si creásemos una clase abstracta **Ovíparo**, | ||
| + | |||
| + | <code php> | ||
| + | trait Oviparo { | ||
| + | |||
| + | private $huevos; | ||
| + | | ||
| + | public function getHuevos() { | ||
| + | return $this-> | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Ahora podríamos hacer: | ||
| + | |||
| + | <code php> | ||
| + | class Reptil extends Invertebrado { | ||
| + | |||
| + | use Oviparo; // Usamos el trait para simular herencia múltiple | ||
| + | private $escamas; | ||
| + | | ||
| + | public function getEscamas() { | ||
| + | return $this-> | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | <WRAP center round info 60%> | ||
| + | Si vamos a usar varios **traits** los separaríamos con comas: '' | ||
| + | </ | ||
| + | |||
| + | |||
| + | Si ahora creamos una nueva clase: | ||
| + | |||
| + | <code php> | ||
| + | class Tortuga extends Reptil { | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Herederá de Vertebrado, Reptil y Ovíparo. | ||
| + | |||
| + | <WRAP center round info 60%> | ||
| + | A la creación de interfaz, clase abstracta y clases concretas es lo que se conoce como **modelado** en programación orientada a objetos. | ||
| + | </ | ||
| + | |||
| + | ===== La clase ReflectionClass ===== | ||
| + | |||
| + | Devuelve información sobre una clase. | ||
| + | |||
| + | <code php> | ||
| + | $reflection = new ReflectionClass(" | ||
| + | Reflexion:: | ||
| + | var_dump($reflexion-> | ||
| + | var_dump($reflexion-> | ||
| + | var_dump($reflexion-> | ||
| + | </ | ||
| + | |||
| + | ===== Constantes predefinidas ===== | ||
| + | |||
| + | * %%__%%FILE%%__%% | ||
| + | * %%__%%LINE%%__%% | ||
| + | * %%__%%CLASS%%__%% | ||
| + | * %%__%%TRAIT%%__%% | ||
| + | * %%__%%METHOD%%__%% | ||
| + | * %%__%%NAMESPACE%%__%% | ||
| + | |||
| + | <code php> | ||
| + | |||
| + | </ | ||
| + | |||
| + | ===== Espacios de nombres ===== | ||
| + | |||
| + | Cuando tenemos varias clases, funciones, etc. Es común que queramos compartirlos (crear una biblioteca) y puede ocurrir que hayamos usado el mismo nombre que otras funciones o clases y al querer usarlas se produce un conflicto porque no se puede distinguir cuál es cuál. | ||
| + | |||
| + | Los espacios de nombres (// | ||
| + | |||
| + | Una analogía es el sistema de archivos de un disco duro: | ||
| + | |||
| + | < | ||
| + | / | ||
| + | / | ||
| + | </ | ||
| + | |||
| + | Hay dos ficheros con el mismo nombre ('' | ||
| + | |||
| + | En PHP se utilizan los espacios de nombres para la creación de bibliotecas evitando el conflicto de nombre de funciones o variables y para simplificar nombres de elementos muy largos y evitar el primer problema en el desarrollo de código reutilizable. | ||
| + | |||
| + | <WRAP center round info 60%> | ||
| + | Los espacios de nombres están disponibles en PHP desde 5.3.0 | ||
| + | </ | ||
| + | |||
| + | |||
| + | Los espacios de nombres nos permiten agrupar clases, interfaces, funciones y constantes relacionadas por lo general en una biblioteca. | ||
| + | |||
| + | ==== Creación ==== | ||
| + | |||
| + | El código que se ve afectado por el espacio de nombres son las clases, interfaces, funciones y constantes. | ||
| + | |||
| + | Se definen con la palabra reservada '' | ||
| + | |||
| + | <code php> | ||
| + | namespace Perro; | ||
| + | |||
| + | const NOMBRE = " | ||
| + | |||
| + | class MiPerro { | ||
| + | |||
| + | // Código | ||
| + | | ||
| + | public function pasearPerro() { | ||
| + | |||
| + | // Código | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Podemos crear subespacios de nombres como si de directorios se tratase: | ||
| + | |||
| + | <code php> | ||
| + | namespace Perro\salchicha; | ||
| + | |||
| + | const NOMBRE = " | ||
| + | |||
| + | class MiPerro { | ||
| + | |||
| + | // Código | ||
| + | | ||
| + | public function pasearPerro() { | ||
| + | |||
| + | // Código | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | También podemos definir varios // | ||
| + | |||
| + | <code php> | ||
| + | namespace Perro { | ||
| + | | ||
| + | const NOMBRE = " | ||
| + | class MiPerro { | ||
| + | |||
| + | // Código | ||
| + | | ||
| + | public function pasearPerro() { | ||
| + | |||
| + | // Código | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | | ||
| + | namespace Gato { | ||
| + | | ||
| + | const NOMBRE = " | ||
| + | class MiGato { | ||
| + | |||
| + | // Código | ||
| + | | ||
| + | public function pasearGato() { | ||
| + | |||
| + | // Código | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ==== Llamada a un espacio de nombres ==== | ||
| + | |||
| + | El manejo de los espacios de nombres es muy similar al uso de un sistema de ficheros de un disco duro: | ||
| + | |||
| + | * Llamar al archivo sin indicar ruta | ||
| + | * Llamar al archivo con una ruta relativa | ||
| + | * Llamar al archivo con una ruta absoluta | ||
| + | |||
| + | Creamos el namespace ('' | ||
| + | |||
| + | <code php> | ||
| + | namespace Animal\Perro\salchica; | ||
| + | |||
| + | const NOMBRE = " | ||
| + | |||
| + | function comer () { | ||
| + | echo "Estoy comiendo, Cinnamon"; | ||
| + | } | ||
| + | |||
| + | class Pasear { | ||
| + | static function paseo() { | ||
| + | echo "Estoy paseando, Cinnamon"; | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | En otro fichero ('' | ||
| + | |||
| + | <code php> | ||
| + | namespace Animal\Perro; | ||
| + | |||
| + | include " | ||
| + | |||
| + | const NOMBRE = " | ||
| + | |||
| + | |||
| + | function comer () { | ||
| + | echo "Estoy comiendo, perro"; | ||
| + | } | ||
| + | |||
| + | class Pasear { | ||
| + | static function paseo() { | ||
| + | echo "Estoy paseando, perro"; | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Si ahora hacemos lo siguiente: | ||
| + | |||
| + | <code php> | ||
| + | // Nombre no cualificado | ||
| + | comer(); | ||
| + | Pasear:: | ||
| + | echo NOMBRE; | ||
| + | </ | ||
| + | |||
| + | Se usa el del '' | ||
| + | |||
| + | Si ahora hacemos: | ||
| + | |||
| + | <code php> | ||
| + | // Nombre cualificado | ||
| + | salchicha\comer(); | ||
| + | salchicha\Pasear:: | ||
| + | echo salchicha\NOMBRE; | ||
| + | </ | ||
| + | |||
| + | Se usará el del '' | ||
| + | |||
| + | Finalmente: | ||
| + | |||
| + | <code php> | ||
| + | // Nombre completamente cualificado | ||
| + | \Animal\Perro\salchicha\comer(); | ||
| + | \Animal\Perro\salchicha\Pasear:: | ||
| + | echo \Animal\Perro\salchicha\NOMBRE; | ||
| + | </ | ||
| + | |||
| + | <WRAP center round tip 60%> | ||
| + | La constante '' | ||
| + | </ | ||
| + | |||
| + | ==== Alias con use ==== | ||
| + | |||
| + | Desde PHP 5.3.0 se ofrecen varias formas de crear alias para apodar una clase, interfaz o espacio de nombres. | ||
| + | |||
| + | Empleamos la palabra reservada '' | ||
| + | |||
| + | Por ejemplo, suponiendo que tenemos un fichero PHP con el namespace '' | ||
| + | |||
| + | <code php> | ||
| + | use Animales\Mamiferos as mascota; | ||
| + | use function Animales\Mamiferos\ladrar as ladrido; | ||
| + | use const Animales\Mamiferos\PERRO as DOG; | ||
| + | |||
| + | $perro = new mascota\Perro; | ||
| + | ladrido(); | ||
| + | echo DOG; | ||
| + | </ | ||
| + | |||
| + | ==== Espacio de nombres global ==== | ||
| + | |||
| + | Puede ocurrir que definamos una función o clase que se llame igual que una interna de PHP. Para distinguir la interna, usamos '' | ||
| + | |||
| + | <code php> | ||
| + | namespace MiNamespace\miSubNamespace; | ||
| + | |||
| + | function fopen($archivo) { | ||
| + | $f = \fopen($archivo); | ||
| + | return $f; | ||
| + | } | ||
| + | |||
| + | class Exception extends \Exception {}; | ||
| + | |||
| + | $e = new Exception(" | ||
| + | $e2 = new \Exception(" | ||
| + | </ | ||
| ===== Funciones interesantes ===== | ===== Funciones interesantes ===== | ||
| Línea 959: | Línea 1467: | ||
| * '' | * '' | ||
| * '' | * '' | ||
| - | * '' | + | * '' |
| * '' | * '' | ||
| * '' | * '' | ||
| * '' | * '' | ||
informatica/programacion/programacion_orientada_a_objetos/php.1679044395.txt.gz · Última modificación: por tempwin
