Público, Protegido, Privado
Parte de la sección Programación Orientada a Objetos del Journey de PHP de Coddy — lección 38 de 91.
¡Bienvenido al capítulo de Encapsulamiento! El encapsulamiento consiste en controlar el acceso a los datos internos de su clase. PHP proporciona tres modificadores de acceso que determinan desde dónde se puede acceder a las propiedades y métodos: public, protected y private.
Así es como funciona cada modificador:
<?php
class BankAccount {
public $accountHolder; // Accesible desde cualquier lugar
protected $accountNumber; // Accesible en esta clase y clases hijas
private $balance; // Accesible solo en esta clase
public function __construct($holder, $number, $balance) {
$this->accountHolder = $holder;
$this->accountNumber = $number;
$this->balance = $balance;
}
public function getBalance() {
return $this->balance;
}
}
$account = new BankAccount("John", "12345", 1000);
echo $account->accountHolder . "\n"; // Funciona - público
echo $account->getBalance(); // Funciona - método público
Salida:
John
1000Intentar acceder a $account->balance directamente causaría un error porque es privado. Lo mismo se aplica a $account->accountNumber desde fuera de la jerarquía de clases. Esta protección garantiza que los datos sensibles solo puedan modificarse a través de métodos controlados.
| Modificador | Misma clase | Clase hija | Fuera |
|---|---|---|---|
public | Sí | Sí | Sí |
protected | Sí | Sí | No |
private | Sí | No | No |
Punto clave: Utiliza private para datos internos que no deberían ser accedidos directamente, protected para datos que las clases hijas necesitan, y public solo para un acceso externo seguro.
Desafío
FácilVamos a construir un sistema seguro de gestión de empleados que demuestre cómo los modificadores de acceso protegen los datos sensibles. Crearás una jerarquía de clases donde diferentes niveles de información son accesibles dependiendo de dónde se esté ejecutando el código: dentro de la clase, en una clase hija o desde el exterior.
Organizarás tu código en tres archivos:
Employee.php— Crea una claseEmployeeque gestione los datos de los empleados con los niveles de visibilidad adecuados. La clase debe tener:- Una propiedad
public$namepara el nombre del empleado (seguro para que cualquiera lo vea) - Una propiedad
protected$employeeIdpara el ID interno (necesario para las clases hijas) - Una propiedad
private$salarypara información sensible de pago (solo esta clase debe acceder a ella directamente)
getSalary()que devuelva el salario privado; esta es la forma controlada de acceder a datos protegidos. También añade un método públicogetPublicInfo()que devuelva"[name] works here".- Una propiedad
Manager.php— Crea una claseManagerque extienda deEmployee. Incluye el archivo Employee. El constructor debe aceptar name, employeeId, salary y un nombre de departamento. Llama al constructor padre con los tres primeros valores, luego almacena el departamento en una propiedad privada. Añade un método públicogetTeamInfo()que devuelva"Manager [name] (ID: [employeeId]) leads [department]". Observa cómo la clase hija puede acceder al$employeeIdprotegido pero necesitaríagetSalary()para acceder al salario privado.main.php— Incluye el archivo Manager. Recibirás cuatro entradas: un nombre, un ID de empleado, un salario (como una cadena que convertirás a entero) y un nombre de departamento. Crea una instancia deManagercon estos valores. Imprime tres líneas:- El nombre del gerente accedido directamente (propiedad pública)
- El resultado de llamar a
getTeamInfo() - El resultado de llamar a
getSalary()
Este desafío muestra la encapsulación en acción: el nombre es libremente accesible, el ID del empleado se comparte con las clases hijas a través de la visibilidad protegida, y el salario permanece bloqueado en la clase padre, accesible solo a través de un método público controlado.
Hoja de referencia
PHP proporciona tres modificadores de acceso para controlar dónde se puede acceder a las propiedades y métodos:
| Modificador | Misma clase | Clase hija | Fuera |
|---|---|---|---|
public | Sí | Sí | Sí |
protected | Sí | Sí | No |
private | Sí | No | No |
Ejemplo:
<?php
class BankAccount {
public $accountHolder; // Accesible desde cualquier lugar
protected $accountNumber; // Accesible en esta clase y clases hijas
private $balance; // Accesible solo en esta clase
public function __construct($holder, $number, $balance) {
$this->accountHolder = $holder;
$this->accountNumber = $number;
$this->balance = $balance;
}
public function getBalance() {
return $this->balance;
}
}
$account = new BankAccount("John", "12345", 1000);
echo $account->accountHolder; // Funciona - público
echo $account->getBalance(); // Funciona - método público
Mejores prácticas:
- Use
privatepara datos internos a los que no se debe acceder directamente - Use
protectedpara datos que las clases hijas necesiten - Use
publicsolo para un acceso externo seguro
Pruébalo tú mismo
<?php
require_once 'Manager.php';
// Leer entradas
$name = trim(fgets(STDIN));
$employeeId = trim(fgets(STDIN));
$salary = intval(trim(fgets(STDIN)));
$department = trim(fgets(STDIN));
// TODO: Crear una instancia de Manager con los valores de entrada
// TODO: Imprimir el nombre del gerente (accedido directamente como propiedad pública)
// TODO: Imprimir el resultado de llamar a getTeamInfo()
// TODO: Imprimir el resultado de llamar a getSalary()
?>Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Programación Orientada a Objetos
1Fundamentos de OOP
Archivos externosIntroducción a OOPClases vs ObjetosLa palabra clave $thisMétodosPropiedadesConstructor (__construct)Destructor (__destruct)Resumen - Calculadora simple4Herencia
Herencia básicaLa palabra clave parent::Sobrescritura de métodosLa palabra clave finalClases abstractasResumen - Jerarquía de empleados7Encapsulamiento
Público, Protegido, PrivadoModificadores de acceso a fondoGetters y SettersOcultamiento de informaciónPromoción de constructor (8.0)Resumen - Sistema de registros de estudiantes10Conceptos avanzados de POO
Composición vs. HerenciaInyección de dependenciasClases anónimasEnums (PHP 8.1)Fibers (PHP 8.1)Clonación de objetos a fondoGeneradores e Iteradores13Patrones de diseño Parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón CompositePatrón Repository2Espacios de nombres y Autoloading
Introducción a los espacios de nombresLa palabra clave useEstándar de Autoloading PSR-4Autoloader de ComposerResumen - Proyecto organizado5Interfaces y Contratos
Introducción a las InterfacesImplementación de InterfacesImplementación de Múltiples InterfacesInterfaz vs Clase AbstractaType Hinting con InterfacesResumen - Calculadora de Formas8Métodos mágicos
Introducción a los métodos mágicos__toString y __debugInfo__get, __set, __isset, __unset__call y __callStatic__clone y clonación de objetos__serialize y __unserializeResumen - Colección personalizada3Propiedades de clase
Propiedades de instancia vs. estáticasConstantes en clasesMétodos y propiedades estáticosPropiedades privadas y protegidasPropiedades de solo lectura (PHP 8.1)Resumen - Gestor de cuenta bancaria6Polimorfismo
Sobrescritura de métodos revisadaPolimorfismo mediante interfacesType Hinting y tipos de uniónEnlace estático tardíoResumen - Procesador de pagos9Traits
Introducción a los TraitsUso de múltiples TraitsResolución de conflictos de TraitsMétodos abstractos en TraitsTraits frente a herencia12Patrones de diseño Parte 1
Introducción a los patrones de diseñoPatrón SingletonPatrón FactoryPatrón ObserverPatrón Strategy