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-1El 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 adminNinguna 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.
Desafío
FácilConstruyamos 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 claseDocumentque sirve como base para todos los documentos. Debe tener una propiedad pública$titley una propiedad protegida$author. El constructor acepta tanto el título como el autor. Incluye un métodofinalllamadogetSignature()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 regulargetContent()que devuelve"Document: [title]".Report.php: Define una claseReportque extiendeDocument. 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: usaparent::__construct()para los dos primeros y después establece el departamento. Sobrescribe el métodogetContent()para que devuelva"Report: [title] ([department])". La claseReporthereda el método finalgetSignature()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 objetoReportcon estos valores. Imprime el resultado degetContent()en la primera línea y después imprime el resultado degetSignature()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()
?>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 la POO
Archivos externosIntroducción a la POOClases frente a objetosLa palabra clave $thisMétodosPropiedadesConstructor (__construct)Destructor (__destruct)Repaso: calculadora simple4Herencia
Herencia básicaLa palabra clave parent::Sobrescritura de métodosLa palabra clave finalClases abstractasRepaso - Jerarquía de empleados7Encapsulación
Público, protegido, privadoModificadores de acceso en profundidadGetters y settersOcultación de la informaciónPromoción del constructor (8.0)Repaso: sistema de registros de estudiantes10Conceptos avanzados de OOP
Composición vs. herenciaInyección de dependenciasClases anónimasEnums (PHP 8.1)Fibras (PHP 8.1)Análisis profundo de la clonación de objetosGeneradores e iteradores13Patrones de diseño Parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón CompositePatrón Repository2Namespaces y carga automática
Introducción a los NamespacesLa palabra clave useEstándar de carga automática PSR-4Autoloader de ComposerRepaso: proyecto organizado5Interfaces y contratos
Introducción a las interfacesImplementación de interfacesImplementación de múltiples interfacesInterfaces vs. clase abstractaTipado con interfacesRepaso - 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 __unserializeRepaso: 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)Repaso: gestor de cuentas bancarias6Polimorfismo
Repaso de la sobrescritura de métodosPolimorfismo mediante interfacesAnotaciones de tipo y tipos uniónEnlace estático tardíoRepaso: procesador de pagos9Traits
Introducción a los TraitsUso de múltiples TraitsResolución de conflictos entre TraitsMétodos abstractos en TraitsTraits frente a la herencia12Patrones de diseño, parte 1
Introducción a los patrones de diseñoPatrón SingletonPatrón FactoryPatrón ObserverPatrón StrategyPractica por tu cuenta: Compilador de PHP online