The final Keyword
Part of the Object Oriented Programming section of Coddy's PHP journey — lesson 24 of 91.
While inheritance and method overriding provide flexibility, sometimes you need to prevent certain classes or methods from being changed. The final keyword locks down your code, ensuring that specific implementations cannot be altered by child classes.
When you mark a method as final, no child class can override it:
<?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();
Output:
ACC-1The getAccountId() method cannot be overridden in SavingsAccount or any other child class. This protects critical functionality that must remain consistent across all account types.
You can also mark an entire class as final to prevent any inheritance:
<?php
final class SecurityManager {
public function authenticate($user) {
return "Authenticating $user";
}
}
$security = new SecurityManager();
echo $security->authenticate("admin");
Output:
Authenticating adminNo class can extend SecurityManager. This is useful for security-sensitive classes or when the class design is complete and shouldn't be modified.
Key Point: Use final on methods to prevent overriding while still allowing inheritance, or on classes to prevent inheritance entirely. It's a tool for protecting critical code that must work exactly as designed.
Challenge
EasyLet's build a document management system that demonstrates how the final keyword protects critical functionality from being modified by child classes.
You'll create three files that work together to manage different document types while ensuring certain security features remain locked:
Document.php— Define aDocumentclass that serves as the base for all documents. It should have a public$titleproperty and a protected$authorproperty. The constructor accepts both title and author. Include afinalmethod calledgetSignature()that returns"Signed by: [author]"— this security feature must never be altered by child classes. Also add a regulargetContent()method that returns"Document: [title]".Report.php— Define aReportclass that extendsDocument. Include the Document file at the top. This class adds a$departmentproperty. The constructor should accept title, author, and department — useparent::__construct()for the first two, then set the department. Override thegetContent()method to return"Report: [title] ([department])". TheReportclass inherits the finalgetSignature()method without being able to change it.main.php— Include the Report file. You'll receive three inputs: the document title, author name, and department. Create aReportobject with these values. Print the result ofgetContent()on the first line, then print the result ofgetSignature()on the second line.
This challenge shows how final methods protect critical functionality — the signature generation remains consistent across all document types, while other methods like getContent() can be customized by each child class. The Report can change how content is displayed, but the signature format is locked in the parent class.
Cheat sheet
The final keyword prevents classes or methods from being modified by child classes.
Final Methods: Mark a method as final to prevent child classes from overriding it:
<?php
class BankAccount {
protected $balance;
final public function getAccountId() {
return "ACC-" . spl_object_id($this);
}
}
class SavingsAccount extends BankAccount {
// Cannot override getAccountId()
}
Final Classes: Mark an entire class as final to prevent any inheritance:
<?php
final class SecurityManager {
public function authenticate($user) {
return "Authenticating $user";
}
}
// No class can extend SecurityManager
Use final on methods to protect specific functionality while allowing inheritance, or on classes to prevent inheritance entirely. This is useful for security-sensitive code or when implementations must remain consistent.
Try it yourself
<?php
require_once 'Report.php';
// Read input
$title = trim(fgets(STDIN));
$author = trim(fgets(STDIN));
$department = trim(fgets(STDIN));
// TODO: Create a Report object with the input values
// TODO: Print the result of getContent()
// TODO: Print the result of getSignature()
?>This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1Fundamentals of OOP
External FilesIntroduction to OOPClasses vs ObjectsThe $this KeywordMethodsPropertiesConstructor (__construct)Destructor (__destruct)Recap - Simple Calculator4Inheritance
Basic InheritanceThe parent:: KeywordMethod OverridingThe final KeywordAbstract ClassesRecap - Employee Hierarchy7Encapsulation
Public, Protected, PrivateAccess Modifiers in DepthGetters and SettersInformation HidingConstructor Promotion (8.0)Recap - Student Records System2Namespaces & Autoloading
Introduction to NamespacesThe use KeywordPSR-4 Autoloading StandardComposer AutoloaderRecap - Organized Project5Interfaces & Contracts
Introduction to InterfacesImplementing InterfacesMultiple Interface ImplementInterface vs Abstract ClassType Hinting with InterfacesRecap - Shape Calculator8Magic Methods
Magic Methods Introduction__toString & __debugInfo__get, __set, __isset, __unset__call & __callStatic__clone & Object Cloning__serialize & __unserializeRecap - Custom Collection11Type System & Error Handling
Type DeclarationsNullable TypesUnion & Intersection TypesException ClassesCustom Exception HierarchyTry, Catch, FinallyRecap - Form Validator14Project: Library Management
Project OverviewBook and User Classes3Class Properties
Instance vs Static PropertiesConstants in ClassesStatic Methods & PropertiesPrivate & Protected PropertiesReadonly Properties (PHP 8.1)Recap - Bank Account Manager6Polymorphism
Method Overriding RevisitedPolymorphism via InterfacesType Hinting & Union TypesLate Static BindingRecap - Payment Processor9Traits
Introduction to TraitsUsing Multiple TraitsTrait Conflict ResolutionAbstract Methods in TraitsTraits vs Inheritance12Design Patterns Part 1
Intro to Design PatternsSingleton PatternFactory PatternObserver PatternStrategy Pattern