Zusammenfassung: In diesem Artikel wird das Konzept des Polymorphismus und seine Anwendung im objektorientierten Design erörtert. Außerdem wird analysiert, wie Polymorphismus in PHP 5 verwendet wird und welche Vor- und Nachteile er hat.
Unterstützung für spätes Binden wurde in neueren Versionen von PHP implementiert. Natürlich gibt es bei der Verwendung der Late-Binding-Funktion immer noch viele Probleme. Wenn Sie eine ältere Version von PHP verwenden (auf meinem Server wird PHP 5.0.1 ausgeführt), kann es sein, dass die Unterstützung für die späte Bindung fehlt. Bitte beachten Sie daher, dass der Code in diesem Artikel möglicherweise nicht in Ihrer spezifischen Version von PHP 5 funktioniert.
1. PHP 5 und Polymorphismus
In diesem Artikel möchten wir einen der wichtigsten Teile der objektorientierten Programmierung besprechen – den Entwurf des Polymorphismus. Um das Problem zu veranschaulichen, verwende ich PHP 5. Bevor Sie weiterlesen, machen Sie bitte klar, dass es in diesem Artikel nicht ausschließlich um PHP geht. Obwohl die Sprache in den letzten beiden Hauptversionen große Fortschritte in der rasanten Entwicklung gemacht hat, wird es noch einige Zeit dauern, bis sie mit ausgereifteren Sprachen wie C++ oder Java mithalten kann.
Wenn Sie ein Anfänger in der objektorientierten Programmierung sind, ist dieser Artikel möglicherweise nicht für Sie geeignet, da dieser Teil des Polymorphismus etwas Besonderes ist: Wenn Sie ihn einmal verstanden haben, werden Sie ihn nie wieder vergessen. Wenn Sie ein wenig über Objektprogrammierung und -design lernen möchten und nicht genau wissen, was es bedeutet, wenn jemand sagt „Ein Objekt ist polymorph“, dann ist dieser Artikel genau das Richtige für Sie.
Am Ende dieses Artikels sollten Sie wissen, was Polymorphismus ist und wie Sie ihn auf objektorientiertes Design anwenden können, und Sie werden die Vor- und Nachteile der Objektprogrammierung in PHP 5 verstehen.
2. Was ist Polymorphismus?
Die Definition von Polymorphismus von dictionary.com lautet „in verschiedenen Formen, Stadien oder Typen in unabhängigen Organisationen oder in derselben Organisation ohne grundlegende Unterschiede auftreten“. Aus dieser Definition können wir schließen, dass Polymorphismus Sexualität eine programmgesteuerte Art ist, dasselbe zu beschreiben Objekt durch mehrere Zustände oder Phasen. Tatsächlich besteht die eigentliche Bedeutung darin, dass wir uns in der tatsächlichen Entwicklung nur auf die Programmierung einer Schnittstelle oder Basisklasse konzentrieren müssen und uns nicht um die spezifische Klasse (Klasse) kümmern müssen, zu der ein Objekt gehört.
Wenn Sie mit Entwurfsmustern vertraut sind, auch wenn Sie nur ein vorläufiges Verständnis haben, werden Sie dieses Konzept verstehen. Tatsächlich ist Polymorphismus möglicherweise das beste Werkzeug in der musterbasierten Designprogrammierung. Es ermöglicht uns, ähnliche Objekte auf logische Weise zu organisieren, sodass wir uns beim Codieren nicht um den spezifischen Typ des Objekts kümmern müssen. Außerdem müssen wir nur eine gewünschte Schnittstelle oder Basisklasse programmieren. Je abstrakter eine Anwendung ist, desto flexibler wird sie – und Polymorphismus ist eine der besten Möglichkeiten, Verhalten zu abstrahieren.
Betrachten wir zum Beispiel eine Klasse namens Person. Wir können Person mit Klassen namens David, Charles und Alejandro unterteilen. Person verfügt über eine abstrakte Methode AcceptFeedback (), und alle Unterklassen müssen diese Methode implementieren. Das bedeutet, dass jeder Code, der eine Unterklasse der Basisklasse Person verwendet, die Methode AcceptFeedback() aufrufen kann. Sie müssen nicht prüfen, ob es sich bei dem Objekt um einen David oder einen Alejandro handelt, es genügt zu wissen, dass es sich um eine Person handelt. Daher muss sich Ihr Code nur auf den „kleinsten gemeinsamen Nenner“ konzentrieren – die Person-Klasse.
Die Person-Klasse in diesem Beispiel könnte auch als Schnittstelle erstellt werden. Natürlich gibt es einige Unterschiede zu den oben genannten, hauptsächlich: Eine Schnittstelle gibt kein Verhalten vor, sondern legt nur eine Reihe von Regeln fest. Eine Person-Schnittstelle erfordert „Sie müssen die AddFeedback()-Methode unterstützen“, während eine Person-Klasse einen Standardcode für die AddFeedback()-Methode bereitstellen kann – Ihr Verständnis davon kann sein: „Wenn Sie AddFeedback() nicht unterstützen möchten, dann.“ Sie sollten eine Standardimplementierung bereitstellen. „Die Auswahl einer Schnittstelle oder einer Basisklasse geht über das Thema dieses Artikels hinaus. Im Allgemeinen müssen Sie jedoch eine Standardmethode über die Basisklasse implementieren.“ Sie können eine Schnittstelle auch verwenden, wenn Sie einfach einen gewünschten Satz an Funktionen skizzieren können, die Ihre Klasse implementiert.
3. Polymorphes Design anwenden
Wir werden weiterhin das Beispiel der Basisklasse Person verwenden und nun eine nicht-polymorphe Implementierung analysieren. Die folgenden Beispiele verwenden verschiedene Arten von Person-Objekten – eine sehr unbefriedigende Art der Programmierung. Beachten Sie, dass die eigentliche Person-Klasse weggelassen wird. Bisher haben wir uns nur mit dem Thema Codeaufrufe beschäftigt.
<?php
$name = $_SESSION['name'];
$myPerson = Person::GetPerson($name);
switch (get_class($myPerson)){
Fall 'David':
$myPerson->AddFeedback('Toller Artikel!', 'Einige Leser', date('Ym-d'));
brechen;
Fall 'Charles':
$myPerson->feedback[] = array('Some Reader', 'Great Editing!');
brechen;
Fall 'Alejandro':
$myPerson->Feedback->Append('Awesome Javascript!');
brechen;
Standard :
$myPerson->AddFeedback('Yay!');
}
?>
Dieses Beispiel zeigt Objekte mit unterschiedlichem Verhalten, und eine Switch-Anweisung wird verwendet, um verschiedene Person-Klassenobjekte zu unterscheiden, um ihre jeweiligen korrekten Operationen auszuführen. Beachten Sie, dass die Feedback-Kommentare hier für verschiedene Bedingungen unterschiedlich sind. Dies ist in der realen Anwendungsentwicklung möglicherweise nicht der Fall. Ich veranschauliche lediglich die Unterschiede, die bei Klassenimplementierungen bestehen.
Ein Beispiel unten verwendet Polymorphismus.
<?php
$name = $_SESSION['name'];
$myPerson = Person::GetPerson($name);
$myPerson->AddFeedback('Toller Artikel!', 'SomeReader', date('Ym-d'));
?>
Beachten Sie, dass es hier keine switch-Anweisung gibt und vor allem Informationen darüber fehlen, welche Art von Objekt Person::GetPerson() zurückgeben wird. Und die andere Person::AddFeedback() ist eine polymorphe Methode. Das Verhalten wird vollständig durch konkrete Klassen gekapselt. Denken Sie daran, ob wir hier David, Charles oder Alejandro verwenden, der aufrufende Code muss nie wissen, was die konkrete Klasse tut, sondern nur die Basisklasse.
Obwohl mein Beispiel nicht perfekt ist, demonstriert es die grundlegende Verwendung von Polymorphismus aus der Perspektive des aufrufenden Codes. Jetzt müssen wir die interne Implementierung dieser Klassen analysieren. Das Tolle an der Ableitung von einer Basisklasse ist, dass die abgeleitete Klasse auf das Verhalten der übergeordneten Klasse zugreifen kann. Dies ist häufig die Standardimplementierung, kann aber auch in Klassenvererbungsketten vorkommen, um komplexeres Verhalten zu erzeugen. Nachfolgend finden Sie eine einfache Demonstration dieser Situation.
<?php
Klasse Person{
Funktion AddFeedback($comment, $sender, $date){
//Feedback zur Datenbank hinzufügen}
}
Klasse David erweitert Person{
Funktion AddFeedback($comment, $sender){
parent::AddFeedback($comment, $sender,
date('Ym-d'));
}
}
?>
Hier wird die Person::AddFeedback-Methode zuerst in der Implementierung der AddFeedback-Methode in der David-Klasse aufgerufen. Möglicherweise stellen Sie fest, dass es die Methodenüberladung in C++, Java oder C# nachahmt. Bedenken Sie, dass dies nur ein vereinfachtes Beispiel ist und der tatsächliche Code, den Sie schreiben, vollständig von Ihrem tatsächlichen Projekt abhängt.
4. Spätes Binden in PHP 5
Meiner Meinung nach ist das späte Binden ein wichtiger Grund, warum Java und C# so überzeugend sind. Sie ermöglichen Basisklassenmethoden, Methoden mit „this“ oder $this aufzurufen (auch wenn sie in der Basisklasse nicht vorhanden sind oder der Aufruf einer Methode in der Basisklasse durch eine andere Version in der geerbten Klasse ersetzt werden kann). Sie können davon ausgehen, dass die folgenden Implementierungen in PHP zulässig sind:
<?php
Klasse Person{
Funktion AddFeedback($messageArray) {
$this->ParseFeedback($messageArray);
//In Datenbank schreiben}
}
Klasse David erweitert Person{
Funktion ParseFeedback($messageArray){
// Führen Sie eine Analyse durch}
}
?>
Denken Sie daran, dass es in der Person-Klasse kein ParseFeedback gibt. Angenommen, Sie haben diesen Teil des Implementierungscodes (für dieses Beispiel), führt dies dazu, dass $myPerson ein David-Objekt ist:
<?php
$myPerson = Person::GetPerson($name);
$myPerson->AddFeedback($messageArray);
?>
Es ist ein Analysefehler aufgetreten! Die allgemeine Fehlermeldung lautet, dass die Methode ParseFeedback nicht vorhanden ist oder ähnliche Informationen vorliegen. Lassen Sie uns über die späte Bindung in PHP 5 sprechen! Als nächstes fassen wir das Konzept der späten Bindung zusammen.
Spätes Binden bedeutet, dass der Methodenaufruf erst im letzten Moment an das Zielobjekt gebunden wird. Dies bedeutet, dass diese Objekte beim Aufruf der Methode zur Laufzeit bereits einen konkreten Typ haben. In unserem obigen Beispiel haben Sie David::AddFeedback() aufgerufen, und da sich $this in David::AddFeedback() auf ein David-Objekt bezieht, können Sie logischerweise davon ausgehen, dass die Methode ParseFeedback() existiert – tatsächlich ist sie jedoch nicht vorhanden existieren, weil AddFeedback() in Person definiert ist und ParseFeedback() von der Person-Klasse aufgerufen wird.
Leider gibt es in PHP 5 keine einfache Möglichkeit, dieses Verhalten zu beseitigen. Das bedeutet, dass Sie möglicherweise etwas machtlos sind, wenn Sie eine flexible polymorphe Klassenhierarchie erstellen möchten.
Ich muss darauf hinweisen, dass ich PHP 5 als Ausdruckssprache für diesen Artikel gewählt habe, einfach weil: Diese Sprache nicht die perfekte Abstraktion des Objektkonzepts realisiert! Dies ist verständlich, da sich PHP 5 noch in der Beta-Version befindet. Da der Sprache nun abstrakte Klassen und Schnittstellen hinzugefügt werden, sollte außerdem auch eine späte Bindung implementiert werden.
5. Zusammenfassung
An diesem Punkt sollten Sie ein grundlegendes Verständnis davon haben, was Polymorphismus ist und warum PHP 5 nicht perfekt ist, um Polymorphismus zu erreichen. Im Allgemeinen sollten Sie wissen, wie Sie ein polymorphes Objektmodell verwenden, um bedingtes Verhalten zu kapseln. Dies erhöht natürlich die Flexibilität Ihrer Objekte und bedeutet, dass weniger Code implementiert werden muss. Darüber hinaus erhöhen Sie die Klarheit Ihres Codes, indem Sie Verhalten kapseln, das bestimmte Bedingungen erfüllt (abhängig vom Zustand des Objekts).