Anonyme Klassen
Teil des Abschnitts Objektorientierte Programmierung der PHP-Journey von Coddy — Lektion 58 von 91.
Manchmal benötigen Sie ein einfaches, einmaliges Objekt ohne den Aufwand, eine vollständige Klasse zu definieren. Anonyme Klassen ermöglichen es Ihnen, Objekte spontan zu erstellen, genau dort, wo Sie sie benötigen. Sie sind besonders nützlich, wenn sie mit Dependency Injection kombiniert werden.
Eine anonyme Klasse wird mit new class gefolgt vom Klassenkörper definiert:
<?php
$logger = new class {
public function log(string $message): void {
echo "Log: $message";
}
};
$logger->log("Hello!");
Ausgabe:
Log: Hello!Anonyme Klassen werden besonders mächtig, wenn sie Interfaces implementieren. Dies ist ideal für Tests oder wenn Sie eine schnelle Implementierung benötigen, ohne Ihre Codebasis mit Klassen zu überladen, die nur einmal verwendet werden:
<?php
interface Notifier {
public function send(string $message): string;
}
function notify(Notifier $notifier, string $msg): string {
return $notifier->send($msg);
}
$result = notify(new class implements Notifier {
public function send(string $message): string {
return "Sent: $message";
}
}, "Test message");
echo $result;
Ausgabe:
Sent: Test messageAnonyme Klassen können auch andere Klassen erweitern, Traits verwenden und Konstruktorargumente akzeptieren. Sie haben vollen Zugriff auf OOP-Funktionen – sie werden lediglich inline definiert und nicht in einer separaten Datei. Verwenden Sie diese, wenn eine vollständige Klassendefinition übertrieben wäre, Sie aber dennoch objektorientiertes Verhalten benötigen.
Aufgabe
EinfachLassen Sie uns ein Datenformatierungssystem erstellen, das die Leistungsfähigkeit anonymer Klassen demonstriert. Anstatt separate Klassendateien für einfache, einmalige Implementierungen zu erstellen, verwenden Sie anonyme Klassen, um schnelle Implementierungen genau dort zu erstellen, wo Sie sie benötigen.
Sie werden Ihren Code in zwei Dateien organisieren:
FormatterInterface.php— Definieren Sie ein Interface namensFormatterInterfacemit einer einzigen Methodeformat(string $data): string. Dies legt den Vertrag fest, dem jeder Formatter folgen muss.main.php— Binden Sie die Interface-Datei ein und erstellen Sie eineDataProcessor-Klasse, die Dependency Injection verwendet, um einen beliebigen Formatter zu akzeptieren. Die Klasse sollte:- Ein
FormatterInterfacein seinem Konstruktor akzeptieren - Eine Methode
process(string $data)haben, die an den injizierten Formatter delegiert und dessen Ergebnis zurückgibt
Sie erhalten zwei Eingaben: einen Formattyp (
"upper"oder"reverse") und einen zu formatierenden String.Erstellen Sie basierend auf dem Formattyp eine anonyme Klasse, die
FormatterInterfaceimplementiert:- Für
"upper": Die Methodeformat()sollte die in Großbuchstaben umgewandelten Daten zurückgeben - Für
"reverse": Die Methodeformat()sollte die umgekehrten Daten zurückgeben
Injizieren Sie Ihre anonyme Klasse in einen
DataProcessor, rufen Sieprocess()mit dem Eingabestring auf und geben Sie das Ergebnis aus.- Ein
Dieser Ansatz ist perfekt, wenn Sie eine schnelle Implementierung benötigen, ohne Ihre Codebasis mit Klassendateien für den Einmalgebrauch zu überladen. Die anonyme Klasse wird inline erstellt, implementiert das erforderliche Interface und kann überall dort übergeben werden, wo dieses Interface erwartet wird.
Spickzettel
Anonyme Klassen ermöglichen es Ihnen, Objekte spontan zu erstellen, ohne eine vollständige Klasse zu definieren. Sie werden mit new class gefolgt vom Klassenkörper definiert:
<?php
$logger = new class {
public function log(string $message): void {
echo "Log: $message";
}
};
$logger->log("Hello!");
Anonyme Klassen können Interfaces implementieren, was sie nützlich für Dependency Injection und Tests macht:
<?php
interface Notifier {
public function send(string $message): string;
}
function notify(Notifier $notifier, string $msg): string {
return $notifier->send($msg);
}
$result = notify(new class implements Notifier {
public function send(string $message): string {
return "Sent: $message";
}
}, "Test message");
Anonyme Klassen unterstützen alle OOP-Features: Sie können andere Klassen erweitern, Traits verwenden und Konstruktor-Argumente akzeptieren. Verwenden Sie sie, wenn eine vollständige Klassendefinition übertrieben wäre, Sie aber dennoch objektorientiertes Verhalten benötigen.
Probier es selbst
<?php
require_once 'FormatterInterface.php';
// TODO: Erstellen Sie eine DataProcessor-Klasse, die:
// - Ein FormatterInterface in ihrem Konstruktor akzeptiert
// - Eine process(string $data) Methode besitzt, die an den Formatter delegiert
// Eingabe lesen
$formatType = trim(fgets(STDIN));
$inputString = trim(fgets(STDIN));
// TODO: Erstellen Sie basierend auf $formatType ("upper" oder "reverse") eine anonyme Klasse,
// die das FormatterInterface implementiert
// - Für "upper": format() sollte die Daten in Großbuchstaben zurückgeben
// - Für "reverse": format() sollte die Daten in umgekehrter Reihenfolge zurückgeben
// TODO: Erstellen Sie einen DataProcessor mit Ihrem anonymen Klassen-Formatter
// Rufen Sie process() mit dem Eingabestring auf und geben Sie das Ergebnis 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 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 – Studentenverwaltungssystem10Fortgeschrittene OOP-Konzepte
Komposition vs. VererbungDependency InjectionAnonyme KlassenEnums (PHP 8.1)Fibers (PHP 8.1)Objekt-Klonen im DetailGeneratoren & Iteratoren2Namensrä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