Introducción a los objetos y clases en PHP

Aprender programación orientada a objetos es esencial para poder desarrollar con los frameworks modernos de PHP como Laravel o Symfony. PHP dejó hace bastante tiempo de ser un lenguaje de plantillas para construir sitios personales para convertirse en un poderoso lenguaje orientado a objetos y uno de los lenguajes más populares de la actualidad: Programming Languages and GitHub.

De hecho la mayoría de los sitios funcionan en PHP y hoy en día existen diferentes motores de plantillas escritos en PHP como Blade o Twig. Pero regresando al tema de OOP (Object Oriented Programming), primero que nada debemos entender el por qué necesitamos clases y objetos:

Las clases nos permiten agrupar información y acciones que podemos ejecutar con dicha información.

Con los objetos y las clases ahora es posible agrupar información y acciones de una forma muy fácil. Lo único que tenemos que pensar es en un nombre genérico para nuestra clase, puesto que las clases y los objetos son conceptos diferentes:

Clase: es un término genérico que, como su nombre lo indica, representa una clase, tipo o conjunto. En mi ejemplo como quiero representar los datos y acciones de una o más personas, voy a llamar a la clase Persona o Person (es buena práctica escribir el código en inglés) y esto es todo lo que hace falta para hacer el “molde” de mi clase:

<?php

class Person
{
 
}

?>

Ahora todas las variables que necesito para representar el estado de cada persona (Person) las voy a declarar dentro de la clase y las voy a llamar propiedades:

<?php
 
class Person
{
    public $firstName = 'John';
    public $lastName = 'Doe';
    private $dateOfBirth = '1980-12-01;
}

?>

Nota que para declarar una propiedad estoy usando 2 palabras clavespublic y private:

  • public quiere decir que la propiedad se puede acceder y modificar fuera del “molde” (esqueleto o contexto) de la clase.
  • private indica que no es posible ni leer ni reescribir la propiedad fuera de la clase y esto nos trae un nuevo concepto muy importante llamado encapsulamiento.

Por otro lado todas las funciones o acciones que van a leer o interactuar con dichos datos (o propiedades) las voy también a convertir en métodos de la clase, tan sólo colocando dichas funciones dentro de la clase:

class Person
{
    public $firstName = 'John';
    public $lastName = 'Doe';
    private $dateOfBirth = '1980-12-01;
 
    public function fullName()
    {
        return "{$this->firstName} {$this->lastName}";
    }
 
    public function age()
    {
        // Calculate age using $this->dateOfBirth...
        return $age;
    }
}

¿A dónde fueron los parámetros?

Como puedes ver el código es similar a lo hecho en la programación estructurada, sin embargo en vez de aceptar argumentos externos ahora estoy trabajando con las propiedades dentro de la clase y esto lo logro utilizando $this->.

Mientras que para trabajar con una variable usamos el signo de dólar $, para interactuar con una propiedad dentro de la clase usamos dólar, seguido de la palabra “this” y una flecha: $this->

 

Declarando un objeto

Mientras que la clase representa el concepto genérico, un objeto es la representación específica de una clase. Cuando tenemos una clase podemos declara uno o más objetos de dicha clase de esta forma:

$john = new Person("John", "Doe", "1980-12-01");

Nota que en este caso usamos el operador “new”, seguido del nombre de la clase y luego los argumentos que acepta el constructor de la clase.

 

Definiendo el constructor de una clase

Lo anterior no va a funcionar porque de hecho nuestra clase no tienen ningún constructor. Un constructor es un método mágico o especial que puede aceptar una serie de argumentos y nos permite inicializar el objeto, por ejemplo asignando las propiedades mínimas requeridas para que nuestro objeto pueda funcionar (por ejemplo tenga una identidad única), en nuestro ejemplo parecemos necesitar entonces el primer nombre, el apellido y la fecha de nacimiento:

<?php
 
class Person
{
    public $firstName = 'John';
    public $lastName = 'Doe';
    private $dateOfBirth = '1980-12-01;
 
    public function __construct($fisrtName, $lastName, $dateOfBirth)
    {
        $this->fisrtName = $firstName;
        $this->lastName = $lastName;
        $this->dateOfBirth = $dateOfBirth;
    }
 
    public function fullName()
    {
        return "{$this->firstName} {$this->lastName}";
    }
 
    public function age()
    {
        // Calculate age using $this->dateOfBirth...
        return $age;
    }
}

Los constructores de todas las clases de PHP son definidos con el mismo nombre __construct y como puedes ver tal como las propiedades y el resto de los métodos, pueden ser públicos o privados, pero por ahora vamos a dejarlo como público. Con este código ya podemos proceder a instanciar nuestro objeto:

$john = new Person("John", "Doe", "1980-12-01");

Nota que el constructor es el único método en nuestro ejemplo que está recibiendo argumentos, una vez que asignamos dichos argumentos a las propiedades de nuestra clase (uno por uno) entonces ya podemos usar dichas propiedades en el resto de los métodos:

class Person
{
    // [El resto del codigo iria aqui]
 
    public function fullName()
    {
        return "{$this->firstName} {$this->lastName}";
    }
}

En este caso dentro del método fullName leemos firstName y lastName.

Ahora en algunas ocasiones queremos leer y/o modificar ciertas propiedades fuera de la clase. Si la propiedad es pública podemos lograrlo así:

$duilio = new Person("John", "Doe", "1980-12-01");
 
$duilio->firstName = 'Duilio';

Pero si la propiedad es privada vamos a obtener una excepción, así que para acceder a ella fuera de la clase debemos declarar métodos conocidos como getters o setters:

class Person
{
    // [El resto del codigo iria aqui]

    public function getDateOfBirth()
    {
        return $this->dateOfBirth;
    }

    public function setDateOfBirth($date)
    {
        $this->dateOfBirth = $date;
    }
}

Los getters o setters son métodos comunes que nos permiten obtener o reemplazar el valor de una propiedad, respectivamente:

  • Con getDateOfBirth obtenemos la fecha de nacimiento de la persona.
  • Con setDateOfBirth reemplazaríamos la fecha de nacimiento de la persona.

Ahora ya no tenemos ninguna limitación para cambiar la fecha de nacimiento de alguien a cualquier otra fecha:

$duilio = new Person("Duilio", "Doe", "1980-12-01");
 
$duilio->setDateOfBirth("2002-01-01");

Gracias al código anterior ahora tengo tan sólo unos 15 años así que puedo dejar de escribir este tutorial e ir a jugar con el Playstation. Lamentablemente esto no es posible en la vida real, así que tampoco debería permitirlo en mi programa, en este caso puedo solucionarlo dejando dateOfBirth como una propiedad privada y eliminando el setter, de esta manera sólo se puede leer el valor de la propiedad mas no modificarlo.

La programación orientada a objetos puede ser un tema fácil de aprender, sin embargo hay tantos conceptos (como abstracción, herencia, interfaces, polimorfismo, etc.) que son imposibles de cubrir en una sola lección, por lo que seguiremos en un futuro.

 

 

Deja un comentario