jairogarcíarincón
La programación orientada a objetos consiste en la creación de código modular y reutilizable mediante el uso de entidades u objetos que representen los datos a manipular.
De este modo, cada objeto tendrá un determinado estado (activo, inactivo, etc.), un cierto comportamiento (ejecutará un método o función) y estará diferenciado del resto de los de su especie por medio de su identidad en forma de variables o atributos. A la entidad o modelo a partir del cual se instancian los diferentes objetos del mismo tipo se le denomina clase.
Vamos a desarrollar un sistema de gestión de coches que permita dar de alta coches con las siguientes características: marca, modelo, color y matrícula.
- Crearíamos un nuevo modelo o clase llamado Coche.
- Dentro de dicha clase añadiríamos las propiedades o atributos marca, modelo, color y matricula.
- Para cada uno de los atributos, dentro de dicha clase añadiríamos sus funciones o métodos get y set que nos permitan modificar o recuperar la información de dicho parámetro.
- Para crear cada uno de los tres coches, asignaríamos a una nueva variable una instancia de la clase Coche.
- Para asignar los atributos a cada coche, haríamos uso de los métodos set() correspondientes.
- Para recuperar los atributos de cada coche, haríamos uso de los métodos get() correspondientes.
El código completo del archivo PHP podría ser similar al siguiente:
<?php
//Crear o definir una clase
class Coche{
//Variables o atributos
var $marca;
var $modelo;
var $color;
var $propietario;
//Funciones o métodos
function setMarca($miMarca){
$this->marca = $miMarca;
}
function getMarca(){
return $this->marca;
}
function setModelo($miModelo){
$this->modelo = $miModelo;
}
function getModelo(){
return $this->modelo;
}
function setColor($miColor){
$this->color = $miColor;
}
function getColor(){
return $this->color;
}
function setPropietario($miPropietario){
$this->propietario = $miPropietario;
}
function getPropietario(){
return $this->propietario;
}
}
//Título
echo "<h1>Ejemplo 1: Definir o instanciar una clase</h1>";
//Instanciar o utilizar una clase
$coche1 = new Coche;
$coche2 = new Coche;
//Accedo a las funciones o métodos set() para configurar el coche 1 (opción 1)
$coche1->setMarca("Wolkswagen");
$coche1->setModelo("Polo");
$coche1->setColor("negro");
$coche1->setPropietario("Rebeca");
//Accedo a las funciones o métodos get() para recuperar la información del coche 1 (opción 1)
echo "
<strong>".$coche1->getPropietario()."</strong> se ha comprado un
<strong>".$coche1->getMarca()." ".$coche1->getModelo()."</strong> de color
<strong>".$coche1->getColor()."</strong>.
";
//Accedo directamente a los atributos para configurar el coche 2 (opción 2)
$coche2->marca = "Toyota" ;
$coche2->modelo = "Corolla";
$coche2->color = "verde";
$coche2->propietario = "Marcos";
//Accedo directamente a los atributos para recuperar la información del coche 2 (opción 2)
echo "
<strong>".$coche2->propietario."</strong> se ha comprado un
<strong>".$coche2->marca." ".$coche2->modelo."</strong> de color
<strong>".$coche2->color."</strong>.
";
El ejemplo anterior sería una primera aproximación al uso de objetos, clases, métodos, atributos e instanciamiento, y ademános permite extraer varias conclusiones importantes:
- Los nombres de clase deben empezar con la palabra reservada class seguido del nombre de la clase en estilo camel-case con la primera en mayúsculas.
- Si quiero utilizar atributos en diferentes métodos de la misma clase, debo definirlos fuera de los métodos para que se comporten de manera global.
- Los métodos pueden llevar atributos de entrada o no llevarlos y se definen mediante la palabra reservada function seguido del nombre del método en estilo camel-case, si bien no es necesario que la primera sea mayúscula.
- Todos los métodos devuelven algo mediante la palabra reservada return, y si ésta no aparece, se entiende que el método devuelve null.
- La palabra reservada $this hace referencia a la clase en la que estoy, y seguida de una flecha derecha me permite acceder tanto a susatributos como a sus métodos.
- Para instanciar una clase utilizamos la palabra reservada new seguida del nombre de la clase.
- Al haber asignado la instancia a un nombre de variable, puedo acceder mediante la flecha derecha a todos sus atributos y métodos.
Ejercicio propuesto 1
- Desarrolla un sistema de gestión de contactos que permita dar de alta contactos con las siguientes características: nombre, apellidos, edad y email.
- Define 3 nuevos contactos con todas sus propiedades.
- Modifica el método setEmail() de modo que no permita asignarlo si la edad del Contacto es inferior a 18 (en cuyo caso el atributo email será "menor de edad".
- Muestra en pantalla el listado de los 3 contactos ordenados por edad.
El uso de constructores nos facilita la instancia de la clase, ya que podremos instanciar y asignar los atributos al mismo tiempo.
Como desventaja, estamos obligados a pasar todos los parámetros definidos en el constructor si no queremos obtener errores.
El ejemplo de coches anterior mediante el uso de constructores podría ser como sigue:
<?php
//Crear o definir una clase
class Coche{
//Variables o atributos
var $marca;
var $modelo;
var $color;
var $propietario;
//Método constructor antiguo
/*function Coche($miMarca,$miModelo,$miColor,$miPropietario){
$this->marca = $miMarca;
$this->modelo = $miModelo;
$this->color = $miColor;
$this->propietario = $miPropietario;
}*/
function __construct($miMarca,$miModelo,$miColor,$miPropietario){
$this->marca = $miMarca;
$this->modelo = $miModelo;
$this->color = $miColor;
$this->propietario = $miPropietario;
}
//Funciones o métodos
function setMarca($miMarca){
$this->marca = $miMarca;
}
function getMarca(){
return $this->marca;
}
function setModelo($miModelo){
$this->modelo = $miModelo;
}
function getModelo(){
return $this->modelo;
}
function setColor($miColor){
$this->color = $miColor;
}
function getColor(){
return $this->color;
}
function setPropietario($miPropietario){
$this->propietario = $miPropietario;
}
function getPropietario(){
return $this->propietario;
}
}
//Título
echo "Ejemplo 2: Constructores
";
//Instancio y configuro los coches
$coche1 = new Coche("Wolkswagen","Polo","negro","Rebeca");
$coche2 = new Coche("Toyota","Corolla","verde","Marcos");
//Accedo a las funciones o métodos get() para recuperar la información del coche 1 (opción 1)
echo "
<strong>".$coche1->getPropietario()."</strong> se ha comprado un
<strong>".$coche1->getMarca()." ".$coche1->getModelo()."</strong> de color
<strong>".$coche1->getColor()."</strong>.
";
//Accedo directamente a los atributos para recuperar la información del coche 2 (opción 2)
echo "
<strong>".$coche2->propietario."</strong> se ha comprado un
<strong>".$coche2->marca." ".$coche2->modelo."</strong> de color
<strong>".$coche2->color."</strong>.
";
Ejercicio propuesto 2
- Modifica el Ejercicio 1 para que permita dar de alta los contactos en una sola línea.
- Modifica la clase de modo que si el valor que se le pasa al email es null pero el contacto es mayor de edad no se cree el contacto.
A medida que vamos complicando nuestro desarrollo, se hace necesario separar en diferentes archivos la lógica de nuestra programación, y de hecho esta será una de las bases para el patrón MVC que veremos más adelante.
Así, el ejemplo anterior podría tener la clase Coche en un archivo diferente o archivo de clase, la cual podríamos requerir y utilizar en cualquier otro archivo.
Archivo de clase Coche.php:
<?php
class Coche
{
//Variables o atributos
var $marca;
var $modelo;
var $color;
var $propietario;
function __construct($miMarca,$miModelo,$miColor,$miPropietario){
$this->marca = $miMarca;
$this->modelo = $miModelo;
$this->color = $miColor;
$this->propietario = $miPropietario;
}
//Funciones o métodos
function setMarca($miMarca){
$this->marca = $miMarca;
}
function getMarca(){
return $this->marca;
}
function setModelo($miModelo){
$this->modelo = $miModelo;
}
function getModelo(){
return $this->modelo;
}
function setColor($miColor){
$this->color = $miColor;
}
function getColor(){
return $this->color;
}
function setPropietario($miPropietario){
$this->propietario = $miPropietario;
}
function getPropietario(){
return $this->propietario;
}
}
Archivo index.php:
//Requiero el archivo de clase para incluirlo en este script
require("Coche.php");
//Título
echo "Ejemplo 3: Instanciar una clase externa
";
//Instancio y configuro los coches
$coche1 = new Coche("Wolkswagen","Polo","negro","Rebeca");
$coche2 = new Coche("Toyota","Corolla","verde","Marcos");
//Accedo a las funciones o métodos get() para recuperar la información del coche 1 (opción 1)
echo "
<strong>".$coche1->getPropietario()."</strong> se ha comprado un
<strong>".$coche1->getMarca()." ".$coche1->getModelo()."</strong> de color
<strong>".$coche1->getColor()."</strong>.
";
//Accedo directamente a los atributos para recuperar la información del coche 2 (opción 2)
echo "
<strong>".$coche2->propietario."</strong> se ha comprado un
<strong>".$coche2->marca." ".$coche2->modelo."</strong> de color
<strong>".$coche2->color."</strong>.
";
De este nuevo ejemplo podemos extraer las siguientes conclusiones, válidas para futuros desarrollos:
- Los nombres de archivos de clase en PHP deben ser idénticos al nombre de la clase declarada en su interior.
- Para poder utilizar un archivo de clase en otro script PHP, podemos hacer uso de la expresión require("ruta-hasta-el-archivo"), que nos permite incluir dicho script dentro del actual, y dará un error fatal de tipo E_COMPILE_ERROR en caso de no encontrarlo.
- Si en vez de require utilizamos include, el funcionamiento es similar pero si no lo encuentra continuará la ejecución ya que solo dará una advertencia de tipo E_WARNING.
- También es posible utilizar require_once() o include_once(), que son idénticos a los anteriores salvo por el hecho de que PHP verificará si ya han sido requeridos o incluidos anteriormente, en cuyo caso no lo volverá a hacer para, por ejemplo, evitar sobre-escribir variables.
Ejercicio propuesto 3
- Modifica el Ejercicio 2 para que la clase Contacto esté en un archivo de clase.
- Modifica la clase para que el contacto no se cree si alguno de los valores es null, (salvo en el caso del email si fuera menor de edad).
Publicado el 03 de Diciembre de 2024