múltiples formas de llamar al método principal en php

90

Al principio estaba confundido por qué ambas llamadas al método en el constructor funcionan, pero ahora creo que lo entiendo. Las clases extensibles heredan los métodos del padre como si estuvieran declarados en la propia clase, Y los métodos existen en el padre, por lo que ambos deberían funcionar.

Ahora me pregunto si hay una forma preferida (es decir, la mejor práctica) de llamar al método (a través de parento this), y si estas son formas realmente idénticas de ejecutar el mismo código, o si hay alguna advertencia al usar uno sobre el otro.

Lo siento, probablemente estoy pensando demasiado en esto.

abstract class Animal {

    function get_species() {

        echo "test";

    }

}

class Dog extends Animal {

    function __construct(){

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

    }

}

$spike = new Dog;
alemán
fuente

Respuestas:

120

Hay tres escenarios (en los que puedo pensar) en los que llamaría a un método en una subclase donde el método sale en la clase principal:

  1. El método no se sobrescribe por subclase, solo existe en padre.

    Este es el mismo que en su ejemplo, y generalmente es mejor usar $this -> get_species(); Tiene razón en que en este caso los dos son efectivamente iguales, pero el método ha sido heredado por la subclase, por lo que no hay razón para diferenciar. Al usarlo $this, permanece consistente entre los métodos heredados y los métodos declarados localmente.

  2. El método es sobrescrito por la subclase y tiene una lógica totalmente única del padre.

    En este caso, obviamente querrá usarlo $this -> get_species();porque no desea que se ejecute la versión principal del método. Nuevamente, al usarlo de manera consistente $this, no necesita preocuparse por la distinción entre este caso y el primero.

  3. El método extiende la clase principal, añadiendo lo que logra el método principal.

    En este caso, aún desea utilizar `$this -> get_species();al llamar al método desde otros métodos de la subclase. El único lugar al que llamará al método principal sería desde el método que sobrescribe el método principal. Ejemplo:

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

El único escenario que puedo imaginar en el que necesitaría llamar al método principal directamente fuera del método principal sería si hicieran dos cosas diferentes y supiera que necesita la versión principal del método, no la local. Este no debería ser el caso, pero si se presentara, la forma limpia de abordar esto sería crear un nuevo método con un nombre como get_parentSpecies()donde todo lo que hace es llamar al método principal:

function get_parentSpecies(){

     parent::get_species();
}

Nuevamente, esto mantiene todo agradable y consistente, permitiendo cambios / modificaciones al método local en lugar de depender del método principal.

Antonio
fuente
¿Cómo lo haría sin "extender"? como si tuviera una "pierna" de Claass dentro de la clase "humano", pero realmente no necesito extenderla, ya que no necesito la funcionalidad "humana" de los padres. ahora, si creara un $leg = new leg()dentro de human, ¿cómo llamaría a las funciones humanas desde el interior de una instancia de pierna $leg?
user151496
@ user151496 Una pierna no es una subclase de humano. Un humano tiene muchas piernas, pero una pierna no es un tipo de humano. Por lo tanto, no debe tener una clase de pierna que herede de un humano, porque una pierna no es un humano.
Beetle
¿Harías de Leg una clase que tenga una interfaz de Leggy? ¿O simplemente que la clase humana implemente Leggy? ¿Cómo podemos definir mejor que una pierna no es exclusiva de los humanos, sino también que las piernas humanas son exclusivamente humanas y una propiedad general de los humanos?
Anthony
2
paamayim nekudotayim es un poco confuso. A primera vista, parece que está llamando a un método estático. Debería haber sido parent-> get_species () en su lugar
peterchaula
Convenido. Las llamadas estáticas son muy confusas en muchos aspectos. Debería actualizar esto en algún momento.
Anthony
5

A menos que no esté entendiendo la pregunta, casi siempre usaría $ this-> get_species porque la subclase (en este caso, perro) podría sobrescribir ese método, ya que lo extiende. Si la clase dog no redefine el método, ambas formas son funcionalmente equivalentes, pero si en algún momento en el futuro decides que quieres que el método get_species en dog imprima "dog", entonces tendrás que revisar todo el código cambialo.

Cuando usa $ this, en realidad es parte del objeto que creó y, por lo tanto, siempre será el más actualizado también (si la propiedad que se usa ha cambiado de alguna manera durante la vida útil del objeto) mientras se usa la clase principal está llamando al método de clase estática.

hackartista
fuente
ese es un buen punto sobre el uso de $ this en caso de que quiera anular el método. Gracias
Jerry