Menu
Coddy logo textTech

La palabra clave final

Parte de la sección Programación Orientada a Objetos del Journey de PHP de Coddy. Lección 24 de 91.

Aunque la herencia y la sobrescritura de métodos proporcionan flexibilidad, a veces necesitas impedir que ciertas clases o métodos se modifiquen. La palabra clave final bloquea tu código, garantizando que las implementaciones específicas no puedan ser alteradas por las clases hijas.

Cuando marcas un método como final, ninguna clase hija puede hacerle override:

<?php
class BankAccount {
    protected $balance;
    
    public function __construct($balance) {
        $this->balance = $balance;
    }
    
    final public function getAccountId() {
        return "ACC-" . spl_object_id($this);
    }
}

class SavingsAccount extends BankAccount {
    public function addInterest() {
        return $this->balance * 0.05;
    }
}

$account = new SavingsAccount(1000);
echo $account->getAccountId();

Salida:

ACC-1

El método getAccountId() no se puede sobrescribir en SavingsAccount ni en ninguna otra clase hija. Esto protege la funcionalidad crítica que debe mantenerse coherente en todos los tipos de cuenta.

También puedes marcar una clase completa como final para impedir cualquier herencia:

<?php
final class SecurityManager {
    public function authenticate($user) {
        return "Authenticating $user";
    }
}

$security = new SecurityManager();
echo $security->authenticate("admin");

Salida:

Authenticating admin

Ninguna clase puede extender SecurityManager. Esto resulta útil para clases sensibles a la seguridad o cuando el diseño de la clase está completo y no debería modificarse.

Punto clave: Usa final en los métodos para evitar la sobrescritura y permitir la herencia, o en las clases para impedir completamente la herencia. Es una herramienta para proteger el código crítico que debe funcionar exactamente como fue diseñado.

challenge icon

Desafío

Fácil

Construyamos un sistema de gestión de documentos que demuestre cómo la palabra clave final protege la funcionalidad crítica para que las clases hijas no puedan modificarla.

Crearás tres archivos que funcionan conjuntamente para gestionar distintos tipos de documentos, garantizando al mismo tiempo que ciertas funciones de seguridad permanezcan bloqueadas:

  • Document.php: Define una clase Document que sirve como base para todos los documentos. Debe tener una propiedad pública $title y una propiedad protegida $author. El constructor acepta tanto el título como el autor. Incluye un método final llamado getSignature() que devuelve "Signed by: [author]". Esta función de seguridad nunca debe ser modificada por las clases hijas. Añade también un método regular getContent() que devuelve "Document: [title]".
  • Report.php: Define una clase Report que extiende Document. Incluye el archivo Document al principio. Esta clase añade una propiedad $department. El constructor debe aceptar el título, el autor y el departamento: usa parent::__construct() para los dos primeros y después establece el departamento. Sobrescribe el método getContent() para que devuelva "Report: [title] ([department])". La clase Report hereda el método final getSignature() sin poder modificarlo.
  • main.php: Incluye el archivo Report. Recibirás tres entradas: el título del documento, el nombre del autor y el departamento. Crea un objeto Report con estos valores. Imprime el resultado de getContent() en la primera línea y después imprime el resultado de getSignature() en la segunda línea.

Este desafío muestra cómo los métodos final protegen la funcionalidad crítica: la generación de la firma se mantiene coherente en todos los tipos de documentos, mientras que otros métodos, como getContent(), pueden personalizarse en cada clase hija. Report puede cambiar cómo se muestra el contenido, pero el formato de la firma queda bloqueado en la clase padre.

Pruébalo tú mismo

<?php
require_once 'Report.php';

// Leer entrada
$title = trim(fgets(STDIN));
$author = trim(fgets(STDIN));
$department = trim(fgets(STDIN));

// TODO: Crea un objeto Report con los valores de entrada

// TODO: Imprime el resultado de getContent()

// TODO: Imprime el resultado de getSignature()
?>
quiz iconPonte a prueba

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

Practica por tu cuenta: Compilador de PHP online