Methoden überschreiben
Teil des Abschnitts Objektorientierte Programmierung der PHP-Journey von Coddy — Lektion 23 von 91.
Manchmal passt die geerbte Methode einer Elternklasse nicht ganz zu dem, was die Kindklasse benötigt. Das Überschreiben von Methoden (Method Overriding) ermöglicht es einer Kindklasse, eine eigene Implementierung einer Methode bereitzustellen, die bereits in der Elternklasse existiert.
Um eine Methode zu überschreiben, definieren Sie einfach eine Methode in der Kindklasse mit demselben Namen wie die Methode der Elternklasse:
<?php
class Animal {
public $name;
public function __construct($name) {
$this->name = $name;
}
public function speak() {
return "$this->name makes a sound";
}
}
class Cat extends Animal {
public function speak() {
return "$this->name says meow";
}
}
$cat = new Cat("Whiskers");
echo $cat->speak();
Ausgabe:
Whiskers says meowDie Klasse Cat ersetzt die speak()-Methode der Elternklasse vollständig durch ihre eigene Version. Wenn Sie speak() für ein Katzen-Objekt aufrufen, verwendet PHP die Implementierung der Kindklasse.
Sie können das Verhalten der Elternklasse auch erweitern, indem Sie parent:: mit Ihrer eigenen Logik kombinieren:
<?php
class Dog extends Animal {
public function speak() {
return parent::speak() . " - woof woof!";
}
}
$dog = new Dog("Rex");
echo $dog->speak();
Ausgabe:
Rex makes a sound - woof woof!Wichtiger Punkt: Das Überschreiben von Methoden ermöglicht es Kindklassen, geerbtes Verhalten anzupassen. Sie können eine Methode vollständig ersetzen oder parent:: verwenden, um auf der ursprünglichen Implementierung aufzubauen.
Aufgabe
EinfachLassen Sie uns ein Benachrichtigungssystem erstellen, das demonstriert, wie Kindklassen durch das Überschreiben von Methoden (Method Overriding) Elternmethoden vollständig ersetzen oder erweitern können.
Sie werden drei Dateien erstellen, die zusammenarbeiten, um verschiedene Arten von Benachrichtigungen zu senden, jede mit ihrem eigenen einzigartigen Verhalten:
Notification.php— Definieren Sie eineNotification-Klasse, die als Basis für alle Benachrichtigungstypen dient. Sie sollte eine öffentliche Eigenschaft$recipientund einen Konstruktor haben, der den Empfänger akzeptiert und setzt. Fügen Sie eine Methodesend($message)hinzu, die"Sending to $this->recipient: $message"zurückgibt.UrgentNotification.php— Definieren Sie eineUrgentNotification-Klasse, dieNotificationerweitert. Binden Sie die Notification-Datei am Anfang ein. Diese Klasse sollte die Methodesend($message)vollständig überschreiben, um"URGENT to $this->recipient: $message!!!"zurückzugeben — beachten Sie das Präfix "URGENT" und die Ausrufezeichen am Ende. Dies demonstriert das vollständige Ersetzen des Verhaltens der Elternklasse.LoggedNotification.php— Definieren Sie eineLoggedNotification-Klasse, dieNotificationerweitert. Binden Sie die Notification-Datei am Anfang ein. Diese Klasse solltesend($message)überschreiben, aber auf der Implementierung der Elternklasse aufbauen: Rufen Sieparent::send($message)auf und hängen Sie" [logged]"an das Ergebnis an. Dies demonstriert das Erweitern statt des Ersetzens von Verhalten.
In main.php binden Sie alle drei Benachrichtigungsklassendateien ein. Sie erhalten zwei Eingaben: den Namen des Empfängers und die zu sendende Nachricht. Erstellen Sie eine Instanz von jedem Benachrichtigungstyp (alle mit demselben Empfänger) und rufen Sie dann für jede Instanz send() mit der Nachricht auf. Geben Sie jedes Ergebnis in einer eigenen Zeile in dieser Reihenfolge aus: reguläre Benachrichtigung, dringende Benachrichtigung, dann protokollierte Benachrichtigung.
Diese Herausforderung zeigt beide Ansätze des Überschreibens von Methoden — die UrgentNotification ersetzt die Logik der Elternklasse vollständig durch ihre eigene Formatierung, während LoggedNotification parent:: verwendet, um das ursprüngliche Verhalten beizubehalten und zu ergänzen.
Spickzettel
Das Überschreiben von Methoden (Method Overriding) ermöglicht es einer Kindklasse, eine eigene Implementierung einer von einer Elternklasse geerbten Methode bereitzustellen.
Um eine Methode zu überschreiben, definieren Sie in der Kindklasse eine Methode mit demselben Namen wie die Methode der Elternklasse:
<?php
class Animal {
public function speak() {
return "makes a sound";
}
}
class Cat extends Animal {
public function speak() {
return "says meow";
}
}
Die Kindklasse ersetzt die Methodenimplementierung der Elternklasse vollständig. Wenn sie für ein Kindobjekt aufgerufen wird, verwendet PHP die Version der Kindklasse.
Um das Verhalten der Elternklasse zu erweitern, anstatt es zu ersetzen, verwenden Sie parent::, um die Elternmethode aufzurufen und Ihre eigene Logik hinzuzufügen:
<?php
class Dog extends Animal {
public function speak() {
return parent::speak() . " - woof woof!";
}
}
Dies kombiniert das ursprüngliche Verhalten der Elternklasse mit zusätzlicher Funktionalität aus der Kindklasse.
Probier es selbst
<?php
require_once 'Notification.php';
require_once 'UrgentNotification.php';
require_once 'LoggedNotification.php';
// Eingabe lesen
$recipient = trim(fgets(STDIN));
$message = trim(fgets(STDIN));
// TODO: Erstellen Sie jeweils eine Instanz jedes Benachrichtigungstyps (alle mit demselben Empfänger)
// TODO: Rufen Sie send() mit der Nachricht für jede Benachrichtigung auf
// Geben Sie jedes Ergebnis in einer eigenen Zeile in dieser Reihenfolge aus:
// 1. Reguläre Benachrichtigung
// 2. Dringende Benachrichtigung
// 3. Protokollierte Benachrichtigung
?>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 die OOPKlassen vs. ObjekteDas $this-SchlüsselwortMethodenEigenschaftenKonstruktor (__construct)Destruktor (__destruct)Rückblick - Einfacher Taschenrechner4Vererbung
Grundlagen der VererbungDas parent:: SchlüsselwortMethoden überschreibenDas final SchlüsselwortAbstrakte KlassenZusammenfassung – Mitarbeiter-Hierarchie7Kapselung
Public, Protected, PrivateZugriffsmodifikatoren im DetailGetter und SetterInformation HidingConstructor Promotion (8.0)Zusammenfassung – Studentenverwaltungssystem2Namensräume & Autoloading
Einführung in NamensräumeDas use-SchlüsselwortPSR-4 Autoloading-StandardComposer AutoloaderZusammenfassung – Organisiertes Projekt5Interfaces & Verträge
Einführung in InterfacesInterfaces implementierenMehrfache Interface-ImplementierungInterface vs. Abstrakte KlasseType Hinting mit InterfacesZusammenfassung – Formen-Rechner8Magische Methoden
Einführung in magische Methoden__toString & __debugInfo__get, __set, __isset, __unset__call & __callStatic__clone & Objekt-Klonen__serialize & __unserializeZusammenfassung - Eigene Collection11Typsystem & Fehlerbehandlung
TypdeklarationenNullable-TypenUnion- & Intersection-TypenException-KlassenEigene Exception-HierarchieTry, Catch, FinallyZusammenfassung - Formular-Validator14Projekt: Bibliotheksverwaltung
ProjektübersichtBuch- und Benutzerklassen3Klasseneigenschaften
Instanz- vs. statische EigenschaftenKonstanten in KlassenStatische Methoden & EigenschaftenPrivate & geschützte EigenschaftenReadonly-Eigenschaften (PHP 8.1)Zusammenfassung – Bankkonto-Manager6Polymorphismus
Method Overriding erneut betrachtetPolymorphismus über InterfacesType Hinting & Union TypesLate Static BindingZusammenfassung – Payment Processor9Traits
Einführung in TraitsVerwendung mehrerer TraitsKonfliktlösung bei TraitsAbstrakte Methoden in TraitsTraits vs. Vererbung12Entwurfsmuster Teil 1
Einführung in EntwurfsmusterSingleton-MusterFactory-MusterObserver-MusterStrategy-Muster15Abschlussherausforderungen
E-Learning-PlattformBanksystemSpielcharakter-EntwicklungFahrzeugvermietung