Polymorphismus im Detail betrachten
Als ich mit dieser Serie begann, sprach ich über die vier Säulen der objektorientierten Programmierung. Jedes dieser Themen ist unten aufgeführt und verlinkt.
An diesem Punkt würde ich normalerweise mit dem nächsten Thema beginnen wollen. Bevor ich dies tue, möchte ich jedoch einen weiteren Post damit verbringen, das Konzept der Polymorphie zu untersuchen.
In meiner bisherigen Karriere habe ich nur wenige Themen gesehen, die diejenigen, die in die objektorientierte Programmierung einsteigen, mehr Verwirrung und Probleme bereiten als Polymorphismus. Daher möchte ich es im Kontext der objektorientierten Programmierung und außerhalb eines bestimmten Frameworks oder einer bestimmten Anwendung (wie WordPress) etwas eingehender diskutieren.
In diesem Beitrag werde ich kurz wiederholen, was wir bisher besprochen haben, und mich dann wieder dem Polymorphismus zuwenden.
Polymorphismus im Detail
Zunächst möchte ich, wie bereits erwähnt, kurz wiederholen, was bisher besprochen wurde, insbesondere wenn Sie einen der vorherigen Beiträge beschönigt haben.
Keine Sorge: Nichts weiter unten schweift in den Code ab. Stattdessen definiert es einfach die Begriffe, die wir verwendet haben, damit Sie eine Vorstellung davon haben, worauf ich mich beziehe, wann immer Sie das Wort in dieser Serie sehen.
Abstraktion
Wir abstrahieren die Idee von etwas in eine Klasse. Stattdessen werden wir Ideen in ihre Klassen abstrahieren. Und hier gibt es eine Schlüsselidee: Eine Klasse sollte ein Substantiv darstellen.
Verkapselung
Kapselung ist wirklich nur ein „großes“ Wort, das sich auf die Idee bezieht, seine Verantwortlichkeiten zu verwalten (oder seine Daten im Auge zu behalten).
Nachlass
Vererbung bezieht sich auf die Idee, dass eine Klasse, obwohl sie ihre eigene Implementierung hat, buchstäblich Eigenschaften, Funktionen und die allgemeine Implementierung von einer übergeordneten Klasse erbt.
Polymorphismus
Polymorphismus ermöglicht es uns, auf eine Klasse eines Typs zu verweisen, wenn sie als ein anderer Typ deklariert werden kann.
Wenn das gesagt ist, denke ich, dass die Dinge hier etwas komplizierter werden können. In den vorherigen Beiträgen habe ich eine Reihe verschiedener Codebeispiele bereitgestellt (und ich fordere Sie auf, sich diese noch einmal anzusehen).
Aber im heutigen Beitrag werde ich versuchen, die Idee ein wenig weiter zu untersuchen, sowohl in der Erklärung als auch im Code.
Bezug auf das Erbe
Wenn es an dieser Stelle nicht offensichtlich ist, ist Polymorphismus stark mit Vererbung verbunden. Stellen Sie sich das so vor: Wenn eine Klasse Eigenschaften und Methoden von einer anderen Klasse erbt, kann sie die übergeordnete Klasse „anstellen“.
Das heißt, wenn Sie so etwas wie eine Content -Klasse und dann zwei Unterklassen haben, eine Post und eine Page, können Sie die Klasse mithilfe des Content -Referenztyps.t instanziieren
Aber zur Laufzeit wird es tatsächlich eine Instanz des Post -Typs sein. Sinn ergeben? Hier ist ein Code als Beispiel.
Zuerst beginnen wir mit der Definition einer Content -Klasse:
<?php
class Content {
protected $title;
protected $content;
protected $metadata;
public function __construct()
{
$this->title = "Hello World!";
$this->content = "This is a sample piece of content.";
$this->metadata = "<This is the metadata of the post.>";
}
public function getTitle()
{
return $this->title;
}
public function getContent()
{
return $this->content;
}
public function getMetadata()
{
return $this->metadata;
}
}
Es hat die allgemeinen Eigenschaften, die Sie wahrscheinlich erwarten – Titel, Inhalt und Metadaten. Zugegeben, diese Eigenschaften sind nur Zeichenfolgen, aber in einer realen Situation könnten sie ausgefeiltere Datenstrukturen sein.
Schauen wir uns nun einen Beitrag an :
<?php
class Post extends Content {
private $author;
public function __construct() {
parent::__construct();
$this->author = "Tom McFarlin";
}
public function getAuthor()
{
return $this->author;
}
}
Was passiert dann, wenn Sie eine Methode in der Post -Klasse aufrufen, wie getTitle, die nicht existiert, aber in der Content -Klasse existiert? Aufgrund der Vererbung sucht es dann nach der Methode in Post, findet sie nicht und beginnt dann mit der Suche in Content.
Wenn es gefunden wird, wird es ausgeführt.
Ähnlich können wir so etwas mit der Page -Klasse und den Inhaltsdaten machen. Zuerst instanziieren wir die Basisklasse, dann legen wir Eigenschaften fest, die für die Page spezifisch sind. In diesem Fall wird es eine Kategorie sein.
<?php
class Page extends Content {
private $category;
public function __construct() {
parent::__construct();
$this->category = "Articles";
}
public function getCategory()
{
return $this->category;
}
}
Wenn wir nun den Code ausführen, können wir mit dem Inhalt beginnen:
<?php
$content = new Content();
echo $content->getTitle();
Beachten Sie, dass dies so aussieht, wie wir es erwarten würden, da wir einen Titel und Inhalt haben. Schauen wir uns auch den Beitrag an :
<?php
// These will work because they reside in the Content base class.
$post = new Post();
echo $post->getAuthor();
echo $post->getTitle();
Dies funktioniert, weil wir einen Autor haben, aber wir haben auch einen Titel, weil er sich in Content befindet. Aber wenn wir versuchen, getAuthor auf einer Instanz von Post aufzurufen?
<?php
// These will work because they reside in the Content base class.
$post = new Post();
echo $post->getAuthor();
echo $post->getTitle();
Wir erhalten einen Fehler, da sich die Methode nicht in dieser Klasse befindet.
Was sollen wir also tun? Da wir in PHP keine starken Typen haben, können wir es nicht in einen anderen Typ umwandeln.
Dafür gibt es Entwurfsmuster, die ich in einer zukünftigen Reihe von Beiträgen erörtern werde, aber PHP lässt dies nicht so einfach zu wie einige andere Sprachen (wie C# oder Java).
Fragen zum Polymorphismus
Hoffentlich gibt Ihnen der obige Code eine Vorstellung davon, wie ein konkreter Typ wie ein Beitrag oder eine Seite implizit die Eigenschaften und Methoden seiner Basisklasse Content zur Laufzeit verwenden kann.
Aber es wirft auch ein paar Fragen auf, oder? Zum Beispiel:
- Warum ist Polymorphismus nützlich? Letztlich ist es eine Frage der Flexibilität. Das heißt, Sie können einen generischen Inhaltstyp schreiben, aber dann einen Beitrag oder eine Seite erstellen, wie wir oben gesehen haben. Dies gibt uns dann alle Vorteile der Content -Klasse und gibt uns beispielsweise auch die Besonderheiten der Post -Klasse.
- Dies scheint eher verwirrend als flexibel zu sein. In gewisser Weise ist es verwirrend, weil der Code ein wenig nachverfolgt werden muss. Das heißt, Sie beginnen möglicherweise in der Post -Klasse und müssen nachschlagen, was die Content -Klasse bietet. Auf der anderen Seite macht es es auch wirklich einfach, eine neue Content -Unterklasse einzuführen und sie dann zur Laufzeit zu verwenden, wenn sie am besten geeignet ist.
In Bezug auf Oberklassen und Unterklassen kommt hier eine solide IDE ins Spiel.
Es ist immer schön, einen Editor zu haben, den Sie mögen, sicher, aber einen zu haben, der intuitiv bestimmen kann, was die Elternklasse, was die Basisklasse usw. ist, kann viel dazu beitragen, zu verfolgen, zu debuggen, zu verfolgen und neue zu schreiben Code.
Aber das ist Inhalt für einen anderen Beitrag, der kommt, nachdem wir über Designmuster gesprochen haben.

