mehrere Möglichkeiten, die übergeordnete Methode in PHP aufzurufen

87

Zuerst war ich verwirrt, warum beide Methodenaufrufe im Konstruktor funktionieren, aber jetzt denke ich, ich verstehe. Die erweiterten Klassen erben die Methoden des übergeordneten Elements, als wären sie in der Klasse selbst deklariert, UND die Methoden sind im übergeordneten Element vorhanden, sodass beide funktionieren sollten.

Jetzt frage ich mich, ob es eine bevorzugte Methode (dh eine bewährte Methode) zum Aufrufen der Methode (über parentoder this) gibt und ob dies wirklich identische Methoden zum Ausführen desselben Codes sind oder ob es bei der Verwendung von Over einige Einschränkungen gibt das andere.

Entschuldigung, ich habe das wahrscheinlich überlegt.

abstract class Animal {

    function get_species() {

        echo "test";

    }

}

class Dog extends Animal {

    function __construct(){

        $this->get_species();
        parent::get_species();

    }

}

$spike = new Dog;
Jerry
quelle

Antworten:

117

Es gibt drei Szenarien (die ich mir vorstellen kann), in denen Sie eine Methode in einer Unterklasse aufrufen würden, in der die Methode in der übergeordneten Klasse beendet wird:

  1. Die Methode wird nicht von der Unterklasse überschrieben, sondern ist nur im übergeordneten Element vorhanden.

    Dies ist das gleiche wie in Ihrem Beispiel, und im Allgemeinen ist es besser, es zu verwenden. $this -> get_species(); Sie haben Recht, dass in diesem Fall die beiden effektiv gleich sind, aber die Methode von der Unterklasse geerbt wurde, sodass es keinen Grund zur Unterscheidung gibt. Durch die Verwendung $thisbleiben Sie konsistent zwischen geerbten Methoden und lokal deklarierten Methoden.

  2. Die Methode wird von der Unterklasse überschrieben und verfügt über eine völlig eindeutige Logik des übergeordneten Elements.

    In diesem Fall möchten Sie natürlich verwenden, $this -> get_species();da die übergeordnete Version der Methode nicht ausgeführt werden soll. Auch hier müssen Sie sich bei konsequenter Verwendung $thiskeine Gedanken über die Unterscheidung zwischen diesem und dem ersten Fall machen.

  3. Die Methode erweitert die übergeordnete Klasse und fügt hinzu, was die übergeordnete Methode erreicht.

    In diesem Fall möchten Sie weiterhin verwenden, `$this -> get_species();wenn Sie die Methode aus anderen Methoden der Unterklasse aufrufen. Der einzige Ort, an dem Sie die übergeordnete Methode aufrufen, ist die Methode, die die übergeordnete Methode überschreibt. Beispiel:

    abstract class Animal {
    
        function get_species() {
    
            echo "I am an animal.";
    
        }
    
     }
    
     class Dog extends Animal {
    
         function __construct(){
    
             $this->get_species();
         }
    
         function get_species(){
    
             parent::get_species();
             echo "More specifically, I am a dog.";
         }
    }
    

Das einzige Szenario, das ich mir vorstellen kann, in dem Sie die übergeordnete Methode direkt außerhalb der überschreibenden Methode aufrufen müssten, wäre, wenn sie zwei verschiedene Dinge tun würden und Sie wüssten, dass Sie die übergeordnete Version der Methode benötigen, nicht die lokale. Dies sollte nicht der Fall sein, aber wenn es sich präsentieren würde, wäre der saubere Weg, dies zu erreichen, eine neue Methode mit einem Namen zu erstellen, wie z. B. get_parentSpecies()die übergeordnete Methode aufzurufen:

function get_parentSpecies(){

     parent::get_species();
}

Auch dies hält alles schön und konsistent und ermöglicht Änderungen / Modifikationen an der lokalen Methode, anstatt sich auf die übergeordnete Methode zu verlassen.

Anthony
quelle
Wie würde ich es ohne "verlängern" tun? Als hätte ich ein Claass "Bein" in der Klasse "Mensch", aber ich muss es nicht wirklich erweitern, da ich die "menschliche" Funktionalität der Eltern nicht brauche. Nun, wenn ich ein $leg = new leg()Inside the humanerstellen würde, wie würde ich die Funktionen des Menschen innerhalb einer Beininstanz aufrufen $leg?
user151496
@ user151496 Ein Bein ist keine Unterklasse von Menschen. Ein Mensch hat viele Beine, aber ein Bein ist keine Art von Mensch. Daher sollten Sie keine Beinklasse haben, die vom Menschen erbt, da ein Bein kein Mensch ist.
Käfer
Würden Sie Leg zu einer Klasse machen, die eine Schnittstelle von Leggy hat? Oder muss die menschliche Klasse nur Leggy implementieren? Wie können wir am besten definieren, dass ein Bein nicht ausschließlich für Menschen ist, sondern auch, dass menschliche Beine einzigartig menschlich und eine allgemeine Eigenschaft des Menschen sind?
Anthony
2
paamayim nekudotayim ist ein bisschen verwirrend. Auf den ersten Blick scheint es, als würden Sie eine statische Methode aufrufen. Es sollte stattdessen parent-> get_species () gewesen sein
peterchaula
Einverstanden. Statische Aufrufe sind in vielerlei Hinsicht sehr verwirrend. Ich sollte dies irgendwann aktualisieren.
Anthony
5

Wenn ich die Frage nicht falsch verstehe, würde ich fast immer $ this-> get_species verwenden, da die Unterklasse (in diesem Fall dog) diese Methode überschreiben könnte, da sie sie erweitert. Wenn der Klassenhund die Methode nicht neu definiert, sind beide Methoden funktional gleichwertig. Wenn Sie jedoch irgendwann in der Zukunft entscheiden, dass die Methode get_species in dog "dog" drucken soll, müssen Sie den gesamten Code und zurückgehen ändern Sie es.

Wenn Sie $ this verwenden, ist es tatsächlich Teil des Objekts, das Sie erstellt haben, und ist daher auch immer das aktuellste (wenn sich die verwendete Eigenschaft während der Lebensdauer des Objekts irgendwie geändert hat), während Sie die übergeordnete Klasse verwenden ruft die statische Klassenmethode auf.

Hackartist
quelle
Das ist ein guter Punkt bei der Verwendung von $ this, falls ich die Methode überschreiben möchte. Danke
Jerry