POO: La Realidad de la Encapsulación
La POO no inventó la encapsulación — C tenía encapsulación perfecta antes de que C++ y Java la debilitaran con los archivos de cabecera.
Por qué importa
La encapsulación se cita a menudo como una de las contribuciones definitorias de la POO, pero Robert C. Martin la desafía. Los programas en C, compilados desde un archivo .c con un encabezado .h, daban a los usuarios acceso solo a las firmas de funciones — la implementación estaba completamente oculta. Eso es encapsulación perfecta. Cuando C++ introdujo archivos de encabezado que tenían que declarar variables miembro privadas, y Java requirió que todo el código fuente de la clase fuera visible, la encapsulación impuesta por el lenguaje que Martin llama "perfecta" fue en realidad degradada.
La lección es que la encapsulación no es una característica del lenguaje — es una disciplina. El lenguaje puede hacerla más fácil o más difícil de romper, pero no puede aplicarla. Un desarrollador escribiendo Python o TypeScript debe elegir proteger el estado interno a través de convenciones de nomenclatura, propiedades y palabras clave private. Sin esa disciplina, los objetos se convierten en cubos de datos transparentes que cualquiera puede corromper.
✗El problema
When all attributes are public, callers can assign any value to any field. Invariants — like "balance must never be negative" — cannot be enforced.
Bad
class BankAccount:
def __init__(self, owner: str, balance: float):
self.owner = owner
self.balance = balance # nothing stops: acc.balance = -999999
account = BankAccount("Alice", 500.0)
account.balance = -99999 # silent corruption — no validation possible
class BankAccount {
owner: string;
balance: number; // any caller can write: acc.balance = -Infinity
constructor(owner: string, balance: number) {
this.owner = owner;
this.balance = balance;
}
}
const acc = new BankAccount("Alice", 500);
acc.balance = -99999; // no guard, no error — invariant broken silently
✓La solución
Private attributes and controlled methods enforce invariants at the boundary. State changes only happen through operations that validate the input first.
Good
class BankAccount:
def __init__(self, owner: str, initial: float):
self._owner = owner
self._balance = initial
@property
def balance(self) -> float: return self._balance
def deposit(self, amount: float) -> None:
if amount <= 0: raise ValueError("Must be positive")
self._balance += amount
def withdraw(self, amount: float) -> None:
if amount <= 0: raise ValueError("Must be positive")
if amount > self._balance: raise ValueError("Insufficient funds")
self._balance -= amount
acc = BankAccount("Alice", 500.0)
acc.deposit(100.0)
print(acc.balance) # 600.0
class BankAccount {
private _balance: number;
private _owner: string;
constructor(owner: string, initialBalance: number) {
this._owner = owner;
this._balance = initialBalance;
}
get balance(): number { return this._balance; }
deposit(amount: number): void {
if (amount <= 0) throw new Error("Must be positive");
this._balance += amount;
}
withdraw(amount: number): void {
if (amount <= 0) throw new Error("Must be positive");
if (amount > this._balance) throw new Error("Insufficient funds");
this._balance -= amount;
}
}
const acc = new BankAccount("Alice", 500);
acc.deposit(100);
console.log(acc.balance); // 600
💡Conclusión clave
La encapsulación es una disciplina aplicada por el programador, no una garantía provista por el lenguaje — el lenguaje simplemente lo hace más fácil o más difícil de romper.
🔧 Algunos ejercicios pueden tener errores. Si algo parece incorrecto, usa el botón Feedback (abajo a la derecha) para reportarlo — nos ayuda a corregirlo rápido.
Pista: La encapsulación es una disciplina impuesta por el programador, no garantizada por el lenguaje.
✗ Tu versión