Das Schlüsselwort final
Teil des Abschnitts Objektorientierte Programmierung der PHP-Journey von Coddy. Lektion 24 von 91.
Während Vererbung und das Überschreiben von Methoden Flexibilität bieten, musst du manchmal verhindern, dass bestimmte Klassen oder Methoden geändert werden. Das Schlüsselwort final sperrt deinen Code und stellt sicher, dass bestimmte Implementierungen von untergeordneten Klassen nicht geändert werden können.
Wenn du eine Methode als final markierst, kann keine untergeordnete Klasse sie überschreiben:
<?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();
Ausgabe:
ACC-1Die Methode getAccountId() kann in SavingsAccount oder einer anderen untergeordneten Klasse nicht überschrieben werden. Dies schützt wichtige Funktionen, die über alle Kontotypen hinweg konsistent bleiben müssen.
Du kannst auch eine gesamte Klasse als final markieren, um jegliche Vererbung zu verhindern:
<?php
final class SecurityManager {
public function authenticate($user) {
return "Authenticating $user";
}
}
$security = new SecurityManager();
echo $security->authenticate("admin");
Ausgabe:
Authenticating adminKeine Klasse kann SecurityManager erweitern. Dies ist nützlich für sicherheitsrelevante Klassen oder wenn das Klassendesign abgeschlossen ist und nicht geändert werden sollte.
Wichtiger Punkt: Verwende final für Methoden, um das Überschreiben zu verhindern und gleichzeitig Vererbung zu ermöglichen, oder für Klassen, um Vererbung vollständig zu verhindern. Es ist ein Werkzeug zum Schutz kritischen Codes, der genau wie vorgesehen funktionieren muss.
Aufgabe
EinfachErstellen wir ein Dokumentverwaltungssystem, das zeigt, wie das Schlüsselwort final kritische Funktionalität davor schützt, von Kindklassen geändert zu werden.
Du erstellst drei Dateien, die zusammenarbeiten, um verschiedene Dokumenttypen zu verwalten und gleichzeitig sicherzustellen, dass bestimmte Sicherheitsfunktionen unverändert bleiben:
Document.php: Definiere eineDocument-Klasse, die als Grundlage für alle Dokumente dient. Sie sollte eine öffentliche Eigenschaft$titleund eine geschützte Eigenschaft$authorbesitzen. Der Konstruktor akzeptiert sowohl Titel als auch Autor. Füge einefinal-Methode namensgetSignature()hinzu, die"Signed by: [author]"zurückgibt. Diese Sicherheitsfunktion darf niemals von Kindklassen geändert werden. Füge außerdem eine reguläre MethodegetContent()hinzu, die"Document: [title]"zurückgibt.Report.php: Definiere eineReport-Klasse, dieDocumenterweitert. Binde die Document-Datei am Anfang ein. Diese Klasse fügt eine Eigenschaft$departmenthinzu. Der Konstruktor sollte Titel, Autor und Abteilung akzeptieren: Verwendeparent::__construct()für die ersten beiden Werte und setze anschließend die Abteilung. Überschreibe die MethodegetContent(), sodass sie"Report: [title] ([department])"zurückgibt. DieReport-Klasse erbt die endgültige MethodegetSignature(), ohne sie ändern zu können.main.php: Binde die Report-Datei ein. Du erhältst drei Eingaben: den Dokumenttitel, den Namen des Autors und die Abteilung. Erstelle mit diesen Werten einReport-Objekt. Gib das Ergebnis vongetContent()in der ersten Zeile aus und anschließend das Ergebnis vongetSignature()in der zweiten Zeile.
Diese Aufgabe zeigt, wie final-Methoden kritische Funktionalität schützen: Die Signaturerzeugung bleibt über alle Dokumenttypen hinweg konsistent, während andere Methoden wie getContent() von jeder Kindklasse angepasst werden können. Die Report-Klasse kann ändern, wie der Inhalt angezeigt wird, aber das Signaturformat ist in der Elternklasse festgelegt.
Probier es selbst
<?php
require_once 'Report.php';
// Eingabe lesen
$title = trim(fgets(STDIN));
$author = trim(fgets(STDIN));
$department = trim(fgets(STDIN));
// TODO: Erstelle ein Report-Objekt mit den Eingabewerten
// TODO: Gib das Ergebnis von getContent() aus
// TODO: Gib das Ergebnis von getSignature() aus
?>Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienEinführung in OOPKlassen vs. ObjekteDas Schlüsselwort $thisMethodenEigenschaftenKonstruktor (__construct)Destruktor (__destruct)Rückblick – Einfacher Taschenrechner4Vererbung
Grundlegende VererbungDas Schlüsselwort parent::MethodenüberschreibungDas Schlüsselwort finalAbstrakte KlassenRückblick – Mitarbeiterhierarchie7Kapselung
Öffentlich, geschützt, privatZugriffsmodifikatoren im DetailGetter und SetterInformationsverbergungKonstruktor-Promotion (8.0)Wiederholung – System zur Verwaltung von Schülerdatensätzen2Namespaces & Autoloading
Einführung in NamespacesDas use-SchlüsselwortPSR-4-Autoloading-StandardComposer-AutoloaderRückblick – Organisiertes Projekt5Schnittstellen & Verträge
Einführung in SchnittstellenSchnittstellen implementierenMehrere Schnittstellen implementierenSchnittstelle vs. abstrakte KlasseTyp-Hinweise mit SchnittstellenRückblick – Formrechner8Magische Methoden
Einführung in magische Methoden__toString & __debugInfo__get, __set, __isset, __unset__call & __callStatic__clone & Objektklonen__serialize & __unserializeRückblick – Benutzerdefinierte Sammlung11Typsystem & Fehlerbehandlung
TypdeklarationenNullable-TypenUnion- & Intersection-TypenException-KlassenBenutzerdefinierte Exception-HierarchieTry, Catch, FinallyRückblick – Formularvalidator14Projekt: Bibliotheksverwaltung
ProjektübersichtBuch- und Benutzerklassen3Klassen-Eigenschaften
Instanz- vs. statische EigenschaftenKonstanten in KlassenStatische Methoden & EigenschaftenPrivate & geschützte EigenschaftenSchreibgeschützte Eigenschaften (PHP 8.1)Zusammenfassung – Bankkonto-Manager6Polymorphie
Methodenüberschreibung erneut betrachtetPolymorphie über SchnittstellenTyp-Hinweise & Union-TypenSpätes statisches BindenRückblick – Zahlungsabwickler9Traits
Einführung in TraitsMehrere Traits verwendenAuflösung von Trait-KonfliktenAbstrakte Methoden in TraitsTraits vs. Vererbung12Entwurfsmuster Teil 1
Einführung in EntwurfsmusterSingleton-MusterFactory-MusterObserver-MusterStrategy-Muster15Abschließende Herausforderungen
E-Learning-PlattformBankingsystemEntwicklung einer SpielfigurFahrzeugvermietungÜbe selbstständig: Online-PHP-Compiler