plusieurs façons d'appeler la méthode parent en php

90

Au début, je ne savais pas pourquoi les deux méthodes appelaient dans le travail du constructeur, mais maintenant je pense que je comprends. Les classes étendues héritent des méthodes du parent comme si elles étaient déclarées dans la classe elle-même, ET les méthodes existent dans le parent, donc les deux devraient fonctionner.

Maintenant, je me demande s'il existe une manière préférée (c'est-à-dire la meilleure pratique) d'appeler la méthode (via parentou this), et si ce sont des façons vraiment identiques d'exécuter le même code, ou s'il y a des mises en garde lors de l'utilisation d'un over L'autre.

Désolé, j'en ai probablement trop réfléchi.

abstract class Animal {

    function get_species() {

        echo "test";

    }

}

class Dog extends Animal {

    function __construct(){

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

    }

}

$spike = new Dog;
jerry
la source

Réponses:

120

Il existe trois scénarios (auxquels je peux penser) où vous appelleriez une méthode dans une sous-classe où la méthode se termine dans la classe parente:

  1. La méthode n'est pas écrasée par la sous-classe, n'existe que dans le parent.

    C'est le même que votre exemple, et généralement il est préférable d'utiliser $this -> get_species(); Vous avez raison de dire que dans ce cas les deux sont effectivement les mêmes, mais la méthode a été héritée par la sous-classe, il n'y a donc aucune raison de différencier. En utilisant, $thisvous restez cohérent entre les méthodes héritées et les méthodes déclarées localement.

  2. La méthode est écrasée par la sous-classe et possède une logique totalement unique du parent.

    Dans ce cas, vous voudrez évidemment l'utiliser $this -> get_species();car vous ne voulez pas que la version parent de la méthode soit exécutée. Encore une fois, en utilisant systématiquement $this, vous n'avez pas à vous soucier de la distinction entre ce cas et le premier.

  3. La méthode étend la classe parent, en ajoutant à ce que la méthode parent réalise.

    Dans ce cas, vous souhaitez toujours l'utiliser `$this -> get_species();lors de l'appel de la méthode à partir d'autres méthodes de la sous-classe. Le seul endroit où vous appellerez la méthode parente proviendrait de la méthode qui remplace la méthode parente. Exemple:

    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.";
         }
    }
    

Le seul scénario que je peux imaginer où vous auriez besoin d'appeler la méthode parente directement en dehors de la méthode de substitution serait s'ils faisaient deux choses différentes et que vous saviez que vous aviez besoin de la version parent de la méthode, pas de la version locale. Cela ne devrait pas être le cas, mais si cela se présentait, la façon la plus simple d'aborder cela serait de créer une nouvelle méthode avec un nom comme get_parentSpecies()là où tout ce qu'elle fait est d'appeler la méthode parente:

function get_parentSpecies(){

     parent::get_species();
}

Encore une fois, cela garde tout beau et cohérent, permettant des changements / modifications à la méthode locale plutôt que de s'appuyer sur la méthode parente.

Anthony
la source
comment le faire sans "prolonger"? comme j'ai une certaine "jambe" à l'intérieur de la classe "humain" mais je n'ai pas vraiment besoin de l'étendre, car je n'ai pas besoin de la fonctionnalité "humaine" du parent. maintenant, si j'ai créé un $leg = new leg()à l'intérieur de human, comment pourrais-je appeler les fonctions humaines à partir d'une instance de jambe $leg?
user151496
@ user151496 Une jambe n'est pas une sous-classe d'humain. Un humain a de nombreuses jambes, mais une jambe n'est pas un type d'humain. Par conséquent, vous ne devriez pas avoir une classe de jambe qui hérite de l'humain, car une jambe n'est pas un humain.
Beetle
Feriez-vous de Leg une classe qui a une interface de Leggy? Ou simplement la classe humaine implémente-t-elle Leggy? Comment définir au mieux qu'une jambe n'est pas exclusive aux humains, mais aussi que les jambes humaines sont uniquement humaines et une propriété générale des humains?
Anthony le
2
paamayim nekudotayim est un peu déroutant. À première vue, il semble que vous appeliez une méthode statique. Cela aurait dû être parent-> get_species () à la place
peterchaula
D'accord. Les appels statiques sont très déroutants à bien des égards. Je devrais mettre à jour ceci à un moment donné.
Anthony
5

À moins que je ne comprenne mal la question, j'utiliserais presque toujours $ this-> get_species parce que la sous-classe (dans ce cas, dog) pourrait écraser cette méthode car elle l'étend. Si la classe dog ne redéfinit pas la méthode, les deux méthodes sont fonctionnellement équivalentes, mais si à un moment donné dans le futur vous décidez que vous voulez que la méthode get_species de dog affiche "dog", vous devrez alors parcourir tout le code et changes le.

Lorsque vous utilisez $ this, il fait en fait partie de l'objet que vous avez créé et sera donc toujours le plus à jour également (si la propriété utilisée a changé d'une manière ou d'une autre pendant la durée de vie de l'objet) tout en utilisant la classe parent appelle la méthode de classe statique.

hackartiste
la source
c'est un bon point sur l'utilisation de $ this au cas où je voudrais remplacer la méthode. Merci
jerry