Ir al contenido principal

Lección 5 · POO en PHP

Por qué clases

Hasta acá los datos viajaban en arrays: un producto era ['nombre' => 'Yerba', 'precio' => 1850]. Eso funciona, pero no dice qué se puede hacer con un producto ni qué datos son obligatorios. Cualquiera puede escribir ['precio' => 'mucho'] y el error aparece tres pantallas después.

Una clase es un molde que define qué datos tiene una cosa y qué operaciones sabe hacer. Un objeto es una cosa concreta hecha con ese molde. La clase Producto dice que todo producto tiene nombre, precio y stock; cada producto del buffet es un objeto de esa clase.

class Producto
{
    public string $nombre;
    public float $precio;
    public int $stock;
}

$yerba = new Producto();
$yerba->nombre = 'Yerba mate 1 kg';
$yerba->precio = 1850.50;
$yerba->stock = 24;

Con new se crea el objeto y con -> se accede a sus datos. La ventaja no es escribir menos: es que el molde declara los datos y, más adelante, las reglas.

Propiedades y métodos

Las variables de la clase se llaman propiedades; las funciones, métodos. Un método trabaja con las propiedades del objeto usando $this:

class Producto
{
    public string $nombre;
    public float $precio;
    public int $stock;

    public function valorEnStock(): float
    {
        return $this->precio * $this->stock;
    }
}

$yerba = new Producto();
$yerba->nombre = 'Yerba mate 1 kg';
$yerba->precio = 1850.50;
$yerba->stock = 24;

echo $yerba->valorEnStock();   // 44412

$this es el objeto actual: cuando se llama $yerba->valorEnStock(), $this es $yerba. El cálculo se escribe una vez y sirve para cualquier producto.

Encapsulamiento

Las propiedades public se pueden modificar desde afuera sin control. Para que eso no pase se declaran private y se accede solo por métodos que validan:

class Producto
{
    private float $precio = 0;

    public function setPrecio(float $precio): void
    {
        if ($precio < 0) {
            throw new InvalidArgumentException('El precio no puede ser negativo');
        }

        $this->precio = $precio;
    }

    public function getPrecio(): float
    {
        return $this->precio;
    }
}

Ahora un precio negativo no puede entrar: el método lo rechaza al momento. Ese es el encapsulamiento: el objeto cuida sus datos y expone solo lo necesario. En el sistema del buffet, Producto, Categoría, Cliente y Venta se arman así.

Constructores

Un constructor es el método que corre al crear el objeto con new. Sirve para exigir los datos obligatorios de entrada:

class Producto
{
    public function __construct(
        private string $nombre,
        private float $precio,
        private int $stock,
    ) {}
}

$yerba = new Producto('Yerba mate 1 kg', 1850.50, 24);

La promoción de propiedades del constructor (declarar private en los parámetros) crea la propiedad y la asigna en un solo paso. Un producto ya no puede existir «a medias»: si falta un dato, el objeto no se crea.

Herencia e interfaces

La herencia permite que una clase tome lo de otra y lo especialice. Todos los productos comparten nombre y precio; una Bebida agrega volumen:

class Bebida extends Producto
{
    public function __construct(
        string $nombre,
        float $precio,
        int $stock,
        private int $mililitros,
    ) {
        parent::__construct($nombre, $precio, $stock);
    }
}

Una interfaz es un contrato: define métodos que una clase se compromete a tener, sin decir cómo. Y un trait es un conjunto de métodos que se reutiliza en varias clases sin herencia.

interface Imprimible
{
    public function resumen(): string;
}

class Producto implements Imprimible
{
    // ...
    public function resumen(): string
    {
        return "{$this->nombre}: \${$this->precio}";
    }
}

La regla práctica: herencia cuando hay una relación «es un» (una bebida es un producto); interfaz cuando varias clases no relacionadas comparten una capacidad; trait para compartir código suelto entre clases.

Resumen

  • Una clase es un molde; un objeto es una cosa hecha con ese molde.
  • Las propiedades guardan datos; los métodos son funciones del objeto; $this es el objeto actual.
  • Encapsulamiento: private + métodos que validan; el objeto cuida sus datos.
  • El constructor exige los datos obligatorios al crear el objeto.
  • Herencia («es un»), interfaz (contrato de capacidades) y trait (código compartido).

En la próxima lección los objetos se guardan en MariaDB: PDO, consultas preparadas y transacciones.

Autoevaluación de la lección 5

Licencia. El material de esta página es elaboración propia de Prof Mauro Bobyk —a partir de las fuentes que detalla el pie del sitio— y se publica bajo una licencia Creative Commons BY-NC-SA 4.0.