Leccion 30 de 75 10 min de lectura

Visibilidad: public, private, protected

Los modificadores de visibilidad controlan quien puede acceder a las propiedades y metodos de una clase. Esto es fundamental para proteger los datos y controlar como se usa tu codigo.

Los tres niveles de visibilidad

PHP ofrece tres modificadores:

  • public: Accesible desde cualquier lugar
  • private: Solo accesible desde la propia clase
  • protected: Accesible desde la clase y sus hijas
PHP
<?php
declare(strict_types=1);

class Usuario
{
    public string $nombre;       // Accesible desde cualquier lugar
    private string $password;    // Solo accesible dentro de esta clase
    protected int $intentos = 0; // Accesible en esta clase y clases hijas
}

$usuario = new Usuario();
$usuario->nombre = 'Ana';     // OK
// $usuario->password = '123'; // Error: propiedad privada
// $usuario->intentos = 5;     // Error: propiedad protegida

public: Sin restricciones

Las propiedades publicas pueden leerse y modificarse desde cualquier parte:

PHP
<?php
declare(strict_types=1);

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

$producto = new Producto();
$producto->nombre = 'Laptop';
$producto->precio = 999.99;

// Problema: cualquiera puede poner valores invalidos
$producto->precio = -500; // Precio negativo (invalido pero permitido)
El problema de public

Sin control, cualquiera puede asignar valores invalidos. Por eso se recomienda usar private con metodos que validen los datos.

private: Proteccion total

Las propiedades privadas solo son accesibles dentro de la clase. Usamos metodos publicos (getters/setters) para acceder de forma controlada:

PHP
<?php
declare(strict_types=1);

class CuentaBancaria
{
    private float $saldo;

    public function __construct(float $saldoInicial)
    {
        $this->saldo = $saldoInicial;
    }

    public function getSaldo(): float
    {
        return $this->saldo;
    }

    public function depositar(float $cantidad): void
    {
        if ($cantidad > 0) {
            $this->saldo += $cantidad;
        }
    }

    public function retirar(float $cantidad): bool
    {
        if ($cantidad > 0 && $cantidad <= $this->saldo) {
            $this->saldo -= $cantidad;
            return true;
        }
        return false;
    }
}

$cuenta = new CuentaBancaria(1000);
$cuenta->depositar(500);
$cuenta->retirar(200);
echo $cuenta->getSaldo(); // 1300

// $cuenta->saldo = 1000000; // Error: no se puede acceder directamente

Este patron se llama encapsulamiento: los datos estan protegidos y solo se modifican a traves de metodos que validan las operaciones.

protected: Para herencia

Las propiedades protegidas son accesibles en la clase y en cualquier clase que herede de ella (veremos herencia en la siguiente leccion):

PHP
<?php
declare(strict_types=1);

class Animal
{
    protected string $nombre;

    public function __construct(string $nombre)
    {
        $this->nombre = $nombre;
    }
}

class Perro extends Animal
{
    public function ladrar(): string
    {
        // Puede acceder a $nombre porque es protected
        return "{$this->nombre} dice: Guau!";
    }
}

$perro = new Perro('Rex');
echo $perro->ladrar(); // Rex dice: Guau!
// echo $perro->nombre; // Error: protected no es accesible desde fuera

Tabla resumen

Modificador Misma clase Clase hija Exterior
public Si Si Si
protected Si Si No
private Si No No

Ejemplo practico: Usuario con validacion

PHP
<?php
declare(strict_types=1);

class Usuario
{
    private string $email;
    private string $passwordHash;

    public function __construct(string $email, string $password)
    {
        $this->setEmail($email);
        $this->setPassword($password);
    }

    public function getEmail(): string
    {
        return $this->email;
    }

    public function setEmail(string $email): void
    {
        if (filter_var($email, FILTER_VALIDATE_EMAIL) === false) {
            throw new InvalidArgumentException('Email invalido');
        }
        $this->email = strtolower($email);
    }

    public function setPassword(string $password): void
    {
        if (strlen($password) < 8) {
            throw new InvalidArgumentException('Password debe tener minimo 8 caracteres');
        }
        $this->passwordHash = password_hash($password, PASSWORD_DEFAULT);
    }

    public function verificarPassword(string $password): bool
    {
        return password_verify($password, $this->passwordHash);
    }
}

$usuario = new Usuario('ANA@Example.COM', 'password123');
echo $usuario->getEmail(); // ana@example.com

if ($usuario->verificarPassword('password123')) {
    echo 'Password correcto';
}

Ejercicios

Ejercicio 1: Producto con stock

Crea una clase Producto con propiedades privadas nombre, precio y stock. El precio no puede ser negativo y el stock no puede bajar de 0. Implementa metodos vender(int $cantidad) y reponer(int $cantidad).

Ver solucion
PHP
<?php
declare(strict_types=1);

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

    public function __construct(string $nombre, float $precio, int $stock = 0)
    {
        $this->nombre = $nombre;
        $this->setPrecio($precio);
        $this->stock = $stock;
    }

    public function getNombre(): string
    {
        return $this->nombre;
    }

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

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

    public function getStock(): int
    {
        return $this->stock;
    }

    public function vender(int $cantidad): bool
    {
        if ($cantidad <= 0 || $cantidad > $this->stock) {
            return false;
        }
        $this->stock -= $cantidad;
        return true;
    }

    public function reponer(int $cantidad): void
    {
        if ($cantidad > 0) {
            $this->stock += $cantidad;
        }
    }
}

$producto = new Producto('Laptop', 999.99, 10);
$producto->vender(3);
echo $producto->getStock(); // 7
$producto->reponer(5);
echo $producto->getStock(); // 12

Ejercicio 2: Contador de instancias

Crea una clase Articulo que cuente cuantas instancias se han creado. Usa una propiedad privada para el contador y un metodo publico para obtener el total.

Ver solucion
PHP
<?php
declare(strict_types=1);

class Articulo
{
    private static int $totalInstancias = 0;
    private string $nombre;

    public function __construct(string $nombre)
    {
        $this->nombre = $nombre;
        self::$totalInstancias++;
    }

    public function getNombre(): string
    {
        return $this->nombre;
    }

    public static function getTotalInstancias(): int
    {
        return self::$totalInstancias;
    }
}

$a1 = new Articulo('Laptop');
$a2 = new Articulo('Mouse');
$a3 = new Articulo('Teclado');

echo Articulo::getTotalInstancias(); // 3

Ejercicio 3: Temperatura

Crea una clase Temperatura que almacene grados Celsius de forma privada. Implementa metodos getCelsius(), getFahrenheit() y setCelsius(). La temperatura minima permitida es -273.15 (cero absoluto).

Ver solucion
PHP
<?php
declare(strict_types=1);

class Temperatura
{
    private float $celsius;

    public function __construct(float $celsius)
    {
        $this->setCelsius($celsius);
    }

    public function getCelsius(): float
    {
        return $this->celsius;
    }

    public function setCelsius(float $celsius): void
    {
        if ($celsius < -273.15) {
            throw new InvalidArgumentException(
                'La temperatura no puede ser menor al cero absoluto (-273.15 C)'
            );
        }
        $this->celsius = $celsius;
    }

    public function getFahrenheit(): float
    {
        return ($this->celsius * 9 / 5) + 32;
    }
}

$temp = new Temperatura(25);
echo $temp->getCelsius() . " C\n";    // 25 C
echo $temp->getFahrenheit() . " F\n"; // 77 F

$temp->setCelsius(100);
echo $temp->getFahrenheit() . " F\n"; // 212 F

// Esto lanzaria excepcion:
// $temp->setCelsius(-300);

¿Te está gustando el curso?

Tenemos cursos premium con proyectos reales y soporte personalizado.

Descubrir cursos premium