diversi modi per chiamare il metodo genitore in php


90

All'inizio ero confuso perché entrambe le chiamate al metodo nel costruttore funzionassero, ma ora penso di capire. Le classi estendenti ereditano i metodi del genitore come se fossero dichiarati nella classe stessa, E i metodi esistono nel genitore, quindi entrambi dovrebbero funzionare.

Ora mi chiedo se esiste un modo preferito (ovvero la migliore pratica) di chiamare il metodo (tramite parento this) e se questi sono modi veramente identici per eseguire lo stesso codice o se ci sono avvertenze quando si usa uno su l'altro.

Scusa, probabilmente ci sto pensando.

abstract class Animal {

    function get_species() {

        echo "test";

    }

}

class Dog extends Animal {

    function __construct(){

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

    }

}

$spike = new Dog;

Risposte:


120

Ci sono tre scenari (a cui posso pensare) in cui chiameresti un metodo in una sottoclasse in cui il metodo esce nella classe genitore:

  1. Il metodo non viene sovrascritto dalla sottoclasse, esiste solo nel genitore.

    Questo è lo stesso del tuo esempio, e generalmente è meglio usare $this -> get_species(); Hai ragione che in questo caso i due sono effettivamente la stessa cosa, ma il metodo è stato ereditato dalla sottoclasse, quindi non c'è motivo di differenziare. Usando $thisrimani coerente tra i metodi ereditati e quelli dichiarati localmente.

  2. Il metodo viene sovrascritto dalla sottoclasse e ha una logica totalmente unica dal genitore.

    In questo caso, dovresti ovviamente usarlo $this -> get_species();perché non vuoi che venga eseguita la versione del genitore del metodo. Ancora una volta, utilizzando costantemente $this, non devi preoccuparti della distinzione tra questo caso e il primo.

  3. Il metodo estende la classe genitore, aggiungendo ciò a ciò che il metodo genitore ottiene.

    In questo caso, si desidera comunque utilizzare `$this -> get_species();quando si chiama il metodo da altri metodi della sottoclasse. L'unico posto in cui chiamerai il metodo genitore sarebbe dal metodo che sovrascrive il metodo genitore. Esempio:

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

L'unico scenario che posso immaginare in cui avresti bisogno di chiamare il metodo genitore direttamente al di fuori del metodo di sovrascrittura sarebbe se facessero due cose diverse e tu sapessi di aver bisogno della versione genitore del metodo, non quella locale. Questo non dovrebbe essere il caso, ma se si presentasse da solo, il modo pulito per avvicinarsi a questo sarebbe creare un nuovo metodo con un nome come get_parentSpecies()dove tutto ciò che fa è chiamare il metodo genitore:

function get_parentSpecies(){

     parent::get_species();
}

Di nuovo, questo mantiene tutto bello e coerente, consentendo cambiamenti / modifiche al metodo locale piuttosto che fare affidamento sul metodo genitore.


come lo farei senza "estendere"? come se avessi un po 'di "gamba" all'interno della classe "umano" ma non ho davvero bisogno di estenderlo, poiché non ho bisogno della funzionalità "umano" del genitore. ora, se ho creato un file$leg = new leg() all'interno di human, come chiamerei le funzioni umane dall'interno di un'istanza di gamba $leg?
user151496

@ user151496 Una gamba non è una sottoclasse di umani. Un essere umano ha molte gambe, ma una gamba non è un tipo di essere umano. Pertanto non dovresti avere una classe di gamba che eredita da umana, perché una gamba non è un essere umano.
Maggiolino

Faresti di Leg una classe con un'interfaccia di Leggy? O semplicemente la classe umana implementa Leggy? Come possiamo definire al meglio che una gamba non è esclusiva degli esseri umani, ma anche che le gambe umane sono unicamente umane e una proprietà generale degli esseri umani?
Anthony,

2
paamayim nekudotayim è un po 'confuso. A prima vista sembra che tu stia chiamando un metodo statico. Avrebbe dovuto essere genitore-> get_species () invece
peterchaula

Concordato. Le chiamate statiche creano molta confusione sotto molti aspetti. Dovrei aggiornarlo ad un certo punto.
Anthony

5

A meno che non stia fraintendendo la domanda, userei quasi sempre $ this-> get_species perché la sottoclasse (in questo caso cane) potrebbe sovrascrivere quel metodo poiché lo estende. Se la classe dog non ridefinisce il metodo allora entrambi i modi sono funzionalmente equivalenti ma se in futuro decidi di volere che il metodo get_species in dog stampi "cane", allora dovresti tornare indietro attraverso tutto il codice e cambiarlo.

Quando usi $ this, in realtà fa parte dell'oggetto che hai creato e quindi sarà sempre anche il più aggiornato (se la proprietà utilizzata è cambiata in qualche modo durante la vita dell'oggetto) mentre si utilizza la classe genitore sta chiamando il metodo della classe statica.


questo è un buon punto sull'utilizzo di $ this nel caso in cui voglio sovrascrivere il metodo. Grazie
jerry
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.