3.2 · Programación orientada a objetos (clases, herencia, interfaces)

Nivel 3 · Bases de datos & POO

3.2Programación orientada a objetos (clases, herencia, interfaces)

Objetivo: pensar y programar en objetos (clases, propiedades, métodos, $this) y dominar la POO (encapsulación, herencia, polimorfismo, interfaces, traits) — el paradigma del PHP moderno y de los frameworks.
Tiempo estimado: 13 min · lectura autónoma · Si solo tienes 5 min: lee «Lo esencial en 30s» + el esquema.

Lo esencial en 30 segundos

  • La clase es un modelo, el objeto una instancia : propiedades (datos) + métodos (comportamientos), new para crear, $this para el objeto actual, __construct para inicializar.
  • La encapsulación protege el estado : propiedades private + getters/setters que validan — el objeto garantiza su propia coherencia.
  • Herencia, interfaces y traits estructuran : extends para especializar, interface para contratar, trait para compartir sin herencia.

Mini-caso hilado — Riad ordena su código espagueti en objetos

Riad, desarrollador web en Constantine, gestiona usuarios y pedidos con arrays y funciones dispersas : un email inválido colado en cualquier parte rompe el envío. Modela una clase Utilisateur (propiedades private, setters que validan, constructor que inicializa), una clase Admin que extends Utilisateur, y una interfaz Notifiable que ambas implementan. Los datos inválidos se rechazan en origen, el código se lee como el negocio.

Este mismo caso vuelve en el curso, el esquema, el guion y el reto 48h.

1. Clases, objetos y encapsulación

La POO organiza el código alrededor de objetos que agrupan datos y comportamientos. La clase es el modelo : propiedades (un usuario tiene nombre, email) y métodos (puede iniciar sesión). Se crean objetos con $user = new User(), el constructor __construct() inicializa en la creación, y $this designa el objeto actual ($this->nom).

La encapsulación controla el acceso vía la visibilidad : public (todas partes), private (solo la clase), protected (clase + descendientes). Se vuelven las propiedades private y se accede por getters/setters que validan : imposible fijar un email inválido directamente. El objeto protege su estado — principio clave de robustez que Riad aplica a cada entidad.

2. Herencia, polimorfismo, interfaces y traits

La herencia (class Admin extends User) hace reutilizar y especializar : Admin obtiene todo de User, añade o redefine métodos. El polimorfismo permite a clases distintas responder al mismo método cada una a su manera — ideal para código genérico. La abstracción oculta la complejidad tras interfaces simples.

Las interfaces son contratos : declaran métodos que una clase DEBE implementar, sin decir cómo — se programa « por contrato », se desacopla (imprescindible para probar). Los traits comparten métodos entre clases sin herencia (PHP solo autoriza un extends). Riad retiene la jerarquía : contrato primero (interfaz), compartir después (trait), especialización al final (extends).

Error frecuente de interpretación: « La POO es solo clases con funciones dentro, y private no sirve para nada ». No. Sin encapsulación (todo public), el estado se corrompe desde todas partes sin control ; sin interfaces, el código se acopla a implementaciones concretas y se vuelve intestable. La POO es una disciplina de protección y de contratos, no un simple orden.
Los cuatro pilares + dos herramientas Del objeto protegido al código desacoplado Clase → objetoPropiedades + métodos, new, $this+Encapsulaciónprivate + getters/setters que validan+Herencia + polimorfismoextends, redefinición, mismo método Interfaces = contratos por implementar ; traits = métodos compartidos sin herencia.
Del objeto protegido al código desacoplado
Versión en texto del esquema (SEO / lectores de pantalla / traducción): 1) Clase y objeto : Riad escribe el modelo Utilisateur y luego instancia cada cliente con new. 2) Encapsulación : las propiedades private solo cambian vía setters que validan el email. 3) Herencia y polimorfismo : Admin extends Utilisateur y redefine sus derechos ; cada rol responde a peutAcceder() a su manera. 4) Contratos y reparto : la interfaz Notifiable y un trait de registro desacoplan el código. Lección : proteger, especializar, contratar.

El $this que se cree otros

« Mi clase Admin modificaba el saldo de los clientes : lo tenía todo en public. »
Encapsulación leída a la mañana siguiente, café cargado

Private primero : un objeto guarda sus asuntos para sí.

🔎 Ejemplo concreto — Clase encapsulada y herencia

Riad modela un usuario que valida su email, y luego un admin.

nom = $nom;
    $this->setEmail($email);
  }
  public function setEmail(string $email): void {
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
      throw new InvalidArgumentException('Correo inválido.');
    }
    $this->email = $email;
  }
  public function getEmail(): string { return $this->email; }
}
class Admin extends Utilisateur {
  public function peutAcceder(string $ressource): bool { return true; }
}

Lectura : constructor que inicializa, setter con respaldo private que valida, herencia que especializa.

Lección : un email inválido se rechaza en origen — el objeto garantiza su coherencia.

Vocabulario de la sección

POO / clase / objeto
Paradigma que organiza el código en objetos (datos + comportamientos) ; la clase es el modelo, el objeto una instancia (new) ; $this = actual, __construct = inicialización.

Ejemplo sencillo: new Utilisateur('Riad', 'riad@exemple-fictif.test').

Lo que no es: funciones y variables dispersas sin modelo.

Reflejo: modelar cada entidad de negocio en clase.

Encapsulación / visibilidad
Agrupar y controlar el acceso : public (todas partes), private (solo la clase), protected (clase + descendientes) ; private + getters/setters para proteger el estado.

Ejemplo sencillo: El setEmail de Riad que rechaza lo inválido.

Lo que no es: propiedades public modificables de cualquier manera.

Reflejo: propiedades private por defecto.

Herencia
class Admin extends User : reutiliza los miembros del padre, añade o redefine ; relación « es un tipo de ».

Ejemplo sencillo: Admin hereda de Utilisateur y redefine peutAcceder().

Lo que no es: copiar-pegar de métodos entre clases.

Reflejo: heredar para especializar, no para copiar.

Polimorfismo / abstracción
Mismo método, comportamientos distintos según la clase ; ocultar la complejidad tras interfaces simples.

Ejemplo sencillo: Cada rol responde a peutAcceder() a su manera.

Lo que no es: un switch gigante sobre el tipo de objeto.

Reflejo: llamar al método, dejar decidir al objeto.

Interfaces / traits
Interfaz : contrato de métodos por implementar (desacoplar, probar). Trait : reparto horizontal de métodos sin herencia.

Ejemplo sencillo: Notifiable implementada por Utilisateur y Commande.

Lo que no es: depender en todas partes de una clase concreta.

Reflejo: depender de interfaces, compartir por traits.

En la práctica — Pensar y programar en objetos

  1. Cread una clase (p. ej. User) con propiedades (nombre, email) y métodos ; instanciad con `new`, inicializad vía __construct, usad $this.
  2. Aplicad la ENCAPSULACIÓN : propiedades private, acceso vía getters/setters que validan ; tipad las propiedades.
  3. Cread una clase que HEREDE (extends) y REDEFINA un método ; observad reutilización y especialización.
  4. Definid una INTERFAZ (contrato) y una clase que la implemente ; explorad un trait para compartir métodos.
Pensáis y programáis en objetos (clases, propiedades, métodos, $this) y domináis la POO (encapsulación, herencia, polimorfismo, interfaces, traits) — el paradigma del PHP moderno y de los frameworks.

Guion listo para decir — presentar su modelado de objetos (30 s)

« Los usuarios están modelados en clase : propiedades private, constructor que inicializa, setters que validan el email. Admin hereda de Utilisateur y redefine sus derechos, y ambos implementan la interfaz Notifiable. Un dato inválido se rechaza en origen. »

Para decir en revisión ; mostrar el setter que lanza la excepción.

Modelo copiar-pegar — clase encapsulada + interfaz

nom = $nom;
    $this->setEmail($email);
  }
  public function setEmail(string $email): void {
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
      throw new InvalidArgumentException('Correo inválido.');
    }
    $this->email = $email;
  }
  public function getEmail(): string { return $this->email; }
}
class Admin extends Utilisateur {
  public function peutAcceder(string $ressource): bool { return true; }
}

Independiente

Una clase Client encapsulada basta para fiabilizar los presupuestos generados.

PYME en Constantine

Riad modela clientes, pedidos y admins vinculados, cada uno validando su estado.

Equipo de producto

Imponer interfaces y encapsulación para módulos testeables entre equipos.

Principiante

Esta semana : una clase con dos propiedades private y un setter que valida.

✓ Buenas prácticas

  • Propiedades private por defecto, acceso vía métodos que validan.
  • Tipar propiedades y firmas (robustez + legibilidad).
  • Programar por contrato (interfaces) para desacoplar y probar.

✗ Errores frecuentes

  • Poner todo en public (estado corruptible desde todas partes).
  • Heredar para copiar código en lugar de especializar un « es un ».
  • Confundir interfaz (contrato) y herencia (reutilización).

Puntos clave

  • La POO organiza el código en OBJETOS (datos + comportamientos). CLASE = modelo ; OBJETO = instancia (new). $this = actual ; __construct = inicialización.
  • ENCAPSULACIÓN : VISIBILIDAD (public/private/protected) ; private + getters/setters que validan para proteger el estado. HERENCIA (extends) : reutilizar y especializar.
  • POLIMORFISMO (mismo método, implementaciones distintas) y ABSTRACCIÓN. INTERFACES = contratos (desacoplar, probar) ; TRAITS = reparto sin herencia.
  • La POO es el RUMBO del PHP moderno y de los FRAMEWORKS : organizar, reutilizar, mantener — un cambio de mentalidad que exige práctica.

Reto 48h — aplica mañana

Escribid 1 clase encapsulada (private + setter que valida) y 1 clase hija que redefina 1 método.

Lista de salida de la sección
  • Distingo clase (modelo) y objeto (instancia).
  • Mis propiedades son private con validación.
  • Heredo para especializar y contrato por interfaz.
Autoevaluación 1-5 : ¿puede existir un estado inválido en mis objetos?¿apuntan mis dependencias a interfaces?

Preguntas frecuentes

¿Por qué pasar a la POO si lo procedural funciona?

Lo procedural dispersa datos y funciones sin estructura : en una app que crece, ya no se sabe qué funciones van con qué datos. La POO agrupa (objeto = datos + comportamientos), modela el negocio (Utilisateur, Commande), protege el estado (encapsulación) y reutiliza (herencia, traits) a la vez que desacopla (interfaces). Es el paradigma de los frameworks del nivel 4 — el rumbo por tomar.

Encapsulación, herencia, interfaces : ¿cómo entenderlos en concreto?

Encapsulación = proteger y agrupar : el saldo de una cuenta solo cambia vía deposer/retirer que verifican (nunca asignación directa). Herencia = « es un tipo de » : Chien extends Animal reutiliza y especializa (aboyer). Interfaz = contrato : la clase se compromete a aportar métodos, el resto del código depende del contrato (testeable). Trait = reparto horizontal cuando un solo extends no basta.

Comprueba tu comprensión

¿Por qué propiedades private + getters/setters?

Recursos adicionales (opcional, para ir más allá)

Examen del nivel 3Preguntas inéditas y más difíciles para validar tus conocimientos