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
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
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)
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
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
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
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
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
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
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);
¿Has encontrado un error o tienes una sugerencia para mejorar esta leccion?
Escribenos¿Te está gustando el curso?
Tenemos cursos premium con proyectos reales y soporte personalizado.
Descubrir cursos premium