Saltar al contenido

La abstracción en la programación orientada a objetos (POO) es un concepto fundamental y se refiere a la capacidad de un lenguaje de programación para representar y manipular conceptos abstractos en el código. En PHP, la abstracción se logra a través de la creación de clases y la implementación de métodos y propiedades que representan las características y comportamientos de un concepto abstracto.

Por ejemplo, podemos crear una clase abstracta llamada "Vehicle" que tenga propiedades como "brand" y "model" y métodos como "start" y "stop". Esta clase abstracta no puede ser instanciada por sí misma, pero puede ser extendida por otras clases más específicas como "Car" o "Motorcycle", que pueden implementar los métodos y propiedades de la clase "Vehicle" de manera específica para cada tipo de vehículo.

La abstracción nos permite crear un modelo conceptual de un objeto o concepto y luego utilizar ese modelo para crear objetos más específicos que heredan las características y comportamientos del modelo conceptual. Esto nos permite reutilizar código y simplificar la creación de objetos complejos.

Además de la creación de clases abstractas, PHP también nos permite utilizar la abstracción a través de la creación de interfaces. Las interfaces son un conjunto de métodos que deben ser implementados por cualquier clase que implemente la interfaz. Esto nos permite asegurarnos de que ciertos métodos estén disponibles en todas las clases que implementen la interfaz, lo que nos permite tratar a estas clases de manera uniforme.

Ejemplo de abstracción en PHP

Aquí tienes un ejemplo de cómo podemos utilizar la abstracción en PHP para crear una jerarquía de clases que represente distintos tipos de vehículos:

<?php

abstract class Vehicle 
{
    protected string $status;

    public function __construct(protected string $brand, protected string $model) {
        $this->status = "off";
    }

    abstract public function start();

    abstract public function stop();

    public function getStatus(): string {
        return $this->status;
    }
}

class Car extends Vehicle 
{
    public function __construct(protected string $brand, protected string $model, protected int $doors) {
        parent::__construct($brand, $model);
    }

    public function start(): void {
        $this->status = "on";
    }

    public function stop(): void {
        $this->status = "off";
    }

    public function getDoors(): int {
        return $this->doors;
    }
}

class Motorcycle extends Vehicle 
{
    public function __construct(protected string $brand, protected string $model, protected int $displacement) {
        parent::__construct($brand, $model);
    }

    public function start(): void {
        $this->status = "on";
    }

    public function stop(): void {
        $this->status = "off";
    }

    public function getDisplacement(): int {
        return $this->displacement;
    }
}

$car = new Car('Ford', 'Fiesta', 4);
$motorcycle = new Motorcycle('Yamaha', 'R1', 1000);

echo 'El coche está ' . $car->getStatus() . PHP_EOL;
echo 'La moto está ' . $motorcycle->getStatus() . PHP_EOL;

$car->start();
$motorcycle->start();

echo 'El coche está ' . $car->getStatus() . PHP_EOL;
echo 'La moto está ' . $motorcycle->getStatus() . PHP_EOL;

En este ejemplo, la clase "Vehicle" tiene propiedades como "brand" y "model" y métodos como "start" y "stop". También tiene un constructor que inicializa estas propiedades y un método "getStatus" que nos permite obtener el estado del vehículo.

Nota que la clase "Vehicle" tiene métodos "start" y "stop" definidos como "abstract". Esto significa que estos métodos no tienen una implementación específica en la clase "Vehicle", sino que deben ser implementados por cualquier clase que extienda "Vehicle".

La clase "Vehicle" es una clase abstracta y no puede ser instanciada por sí misma. En su lugar, debemos crear otras clases que extiendan "Vehicle" y proporcionen implementaciones específicas de los métodos "start" y "stop".

En el ejemplo anterior, la clase "Car" extiende la clase abstracta "Vehicle" y proporciona implementaciones específicas para los métodos "start" y "stop". También tiene una propiedad privada "doors" y un método "getDoors" para obtener el número de puertas del automóvil.

Una vez que hayamos creado la clase "Car", podemos crear una instancia de la misma y utilizar sus propiedades y métodos.

Si deseamos añadir más abstracción a nuestro código, podemos hacer uso de interfaces para la clase abstracta Vehicle de la siguiente forma:

<?php

interface Startable
{
    public function start();
}

interface Stoppable
{
    public function stop();
}

abstract class Vehicle implements Startable, Stoppable {

}

Todas las clases que extiendan de la clase abstracta "Vehicle" deberán implementar cada una de las interfaces exactamente igual que con el código anterior, ya que la interfaz así lo exige.

Los cuatro pilares de la POO

La abstracción es uno de los cuatro pilares de la programación orientada a objetos. Los otros tres son la encapsulación, que protege el estado interno de un objeto; la herencia, que permite que una clase reutilice y extienda a otra; y el polimorfismo, que hace que un mismo método se comporte de forma distinta según el objeto que lo ejecuta.

Las clases abstractas y las interfaces que has visto en este artículo son precisamente el mecanismo que sostiene al polimorfismo: defines el contrato una vez y cada clase concreta lo cumple a su manera.

Conclusiones

En conclusión, la abstracción es un concepto clave en la programación orientada a objetos y nos permite crear modelos conceptuales de objetos y conceptos abstractos y luego utilizar esos modelos para crear objetos más específicos y reutilizar código de manera efectiva. En PHP, podemos utilizar la abstracción a través de la creación de clases abstractas y de interfaces para asegurarnos de que ciertos métodos estén disponibles en todas las clases que implementen esas interfaces.


Si quieres dominar PHP 8 de principio a fin, con la POO aplicada a proyectos reales, tienes la Ruta de aprendizaje de PHP 8.

Rutas de aprendizaje