php'de üst yöntemi çağırmanın birden çok yolu


90

İlk başta, yapıcıdaki her iki yöntem çağrısının da neden çalıştığını kafam karışmıştı, ama şimdi anladığımı düşünüyorum. Genişleyen sınıflar, ebeveynin yöntemlerini, sınıfın kendisinde bildirilmiş gibi miras alır VE yöntemler üstte bulunur, bu nedenle her ikisi de çalışmalıdır.

Şimdi, yöntemi (aracılığıyla parentveya aracılığıyla) çağırmanın tercih edilen bir yolu (yani en iyi uygulama) olup thisolmadığını ve bunların aynı kodu çalıştırmanın gerçekten aynı yolları olup olmadığını veya bir over kullanırken herhangi bir uyarı olup olmadığını merak ediyorum . diğeri.

Üzgünüm, muhtemelen bunu fazla düşündüm.

abstract class Animal {

    function get_species() {

        echo "test";

    }

}

class Dog extends Animal {

    function __construct(){

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

    }

}

$spike = new Dog;

Yanıtlar:


120

Üst sınıfta yöntemin çıktığı bir alt sınıfta bir yöntemi çağıracağınız üç senaryo (düşünebildiğim) vardır:

  1. Yöntemin üzerine alt sınıf tarafından yazılmaz, yalnızca üst sınıfta bulunur.

    Bu, örneğinizle aynıdır ve genellikle kullanmak daha iyidir $this -> get_species(); Haklısınız, bu durumda ikisi etkili bir şekilde aynıdır, ancak yöntem alt sınıf tarafından miras alınmıştır, bu nedenle ayırt etmek için bir neden yoktur. Kullanarak $this, miras alınan yöntemler ve yerel olarak bildirilen yöntemler arasında tutarlı kalırsınız.

  2. Yöntemin üzerine alt sınıf tarafından yazılır ve üst sınıftan tamamen benzersiz bir mantığa sahiptir.

    Bu durumda, $this -> get_species();metodun ebeveyn sürümünün çalıştırılmasını istemediğiniz için açıkça kullanmak isteyeceksiniz. Yine, sürekli kullanarak $this, bu vaka ile ilk vaka arasındaki ayrım konusunda endişelenmenize gerek yok.

  3. Yöntem, ana yöntemin başardıklarına ek olarak ana sınıfı genişletir.

    Bu durumda, `$this -> get_species();yöntemi alt sınıfın diğer yöntemlerinden çağırırken kullanmak istersiniz . Ana yöntemi arayacağınız tek yer, ana yöntemin üzerine yazan yöntem olacaktır. Misal:

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

Üst yöntemi, geçersiz kılma yönteminin hemen dışında nerede çağırmanız gerektiğini hayal edebildiğim tek senaryo, iki farklı şey yapmaları ve yerel değil, yöntemin ebeveyn sürümüne ihtiyacınız olduğunu biliyor olmanız olabilir. Durum böyle olmamalı, ancak eğer kendini gösterdiyse, buna yaklaşmanın temiz yolu, get_parentSpecies()yaptığı tek şey ana yöntemi çağırmak gibi bir adla yeni bir yöntem oluşturmak olacaktır :

function get_parentSpecies(){

     parent::get_species();
}

Yine, bu her şeyin güzel ve tutarlı olmasını sağlar ve ana yönteme güvenmek yerine yerel yöntemde değişikliklere / düzenlemelere izin verir.


"uzatmadan" nasıl yaparım? "insan" sınıfının içinde bir "bacak" cümlesine sahip olduğum gibi, ancak ebeveynin "insan" işlevselliğine ihtiyacım olmadığı için onu genişletmeye gerçekten ihtiyacım yok. şimdi, eğer bir $leg = new leg()iç yaratırsam, humanbir bacak örneğinin içinden insanın işlevlerini nasıl çağırırım $leg?
user151496

@ user151496 Bacak, insanın alt sınıfı değildir. Bir insanın birçok bacağı vardır, ancak bir bacak bir tür insan değildir. Bu nedenle, insandan miras kalan bir bacak sınıfınız olmamalıdır, çünkü bacak insan değildir.
Beetle

Leg'i Leggy arayüzüne sahip bir sınıf yapar mısın? Ya da sadece İnsan sınıfı Leggy'yi mi uyguluyor? Bir bacağın insanlara özel olmadığını, aynı zamanda insan bacaklarının benzersiz bir şekilde insan ve insanların genel bir özelliği olduğunu en iyi nasıl tanımlayabiliriz?
Anthony

2
paamayim nekudotayim biraz kafa karıştırıcı. İlk bakışta statik bir yöntem çağırıyormuşsunuz gibi görünüyor. Bunun yerine parent-> get_species ()
olmalıydı

Kabul. Statik çağrılar birçok açıdan çok kafa karıştırıcıdır. Bunu bir noktada güncellemeliyim.
Anthony

5

Soruyu yanlış anlamıyorsam, neredeyse her zaman $ this-> get_species kullanırım çünkü alt sınıf (bu durumda köpek) onu genişlettiği için bu yöntemin üzerine yazabilir. Köpek sınıfı yöntemi yeniden tanımlamazsa, her iki yol da işlevsel olarak eşdeğerdir, ancak gelecekte bir noktada köpekte get_species yönteminin "köpek" yazması gerektiğine karar verirseniz, o zaman tüm kodu gözden geçirmeniz ve değiştir.

$ This kullandığınızda, aslında oluşturduğunuz nesnenin bir parçasıdır ve bu nedenle her zaman en güncel de olacaktır (eğer kullanılan özellik nesnenin ömrü boyunca bir şekilde değişmişse) üst sınıf kullanılırken statik sınıf yöntemini çağırıyor.


Bu, yöntemi geçersiz kılmak istemem durumunda $ this kullanmak için iyi bir nokta. Teşekkürler
jerry
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.