php中调用父方法的多种方法


90

起初,我很困惑为什么构造器中的两个方法都起作用,但是现在我想我明白了。扩展类继承父类的方法,就像它们是在类本身中声明的一样,并且方法存在于父类中,因此两者都应该起作用。

现在,我想知道是否有一种首选的方法(即最佳实践)调用该方法(通过parentthis),这些是否是执行同一代码的真正相同的方法,或者在使用一种以上方法时是否存在任何警告?另一个。

抱歉,我可能在考虑这个问题。

abstract class Animal {

    function get_species() {

        echo "test";

    }

}

class Dog extends Animal {

    function __construct(){

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

    }

}

$spike = new Dog;

Answers:


120

在三种情况下(我可以想到),您将在子类中调用方法而该方法在父类中退出:

  1. 方法不会被子类覆盖,仅存在于父类中。

    这与您的示例相同,通常最好使用$this -> get_species(); 您是对的,在这种情况下,两者实际上是相同的,但是该方法已被子类继承,因此没有理由进行区分。通过使用,$this您可以在继承的方法和本地声明的方法之间保持一致。

  2. 方法被子类覆盖,并且从父类具有完全独特的逻辑。

    在这种情况下,您显然要使用,$this -> get_species();因为您不希望执行方法的父版本。同样,通过始终使用$this,您无需担心这种情况与第一种情况之间的区别。

  3. 方法扩展了父类,并添加了父方法所实现的功能。

    在这种情况下,`$this -> get_species();从子类的其他方法调用该方法时仍要使用。您将要调用父方法的一个地方是覆盖父方法的方法。例:

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

我可以想象的唯一情况是,您需要在覆盖方法之外直接调用父方法的情况是,如果它们做了两项不同的操作,并且您知道您需要方法的父版本,而不是本地版本。事实并非如此,但是如果它确实能够展现自己,那么解决此问题的干净方法将是创建一个新方法,其名称类似于get_parentSpecies()调用父方法:

function get_parentSpecies(){

     parent::get_species();
}

同样,这可以使所有内容保持良好和一致,从而允许对本地方法进行更改/修改,而​​不是依赖于父方法。


没有“扩展”,我该怎么办?就像我在“人”类中有一些“腿”一样,但我真的不需要扩展它,因为我不需要父母的“人”功能。现在,如果我在$leg = new leg()内部创建一个human,如何从一个腿实例内部调用人的功能$leg
user151496

@ user151496腿不是人类的子类。一个人有很多腿,但腿不是人的一种。因此,您不应拥有从人类继承的一类腿,因为腿不是人。
甲壳虫2016年

您是否可以将Leg设置为具有Leggy界面的类?还是只是人类课实施了Leggy?我们怎样才能最好地定义一条腿不是人类专有的,而是人类的腿是唯一的人类并且是人类的一般财产?
安东尼

2
paamayim nekudotayim有点令人困惑。乍一看,似乎您正在调用静态方法。它应该是parent-> get_species()而不是
peterchaula

同意 静态调用在很多方面都很令人困惑。我应该在某个时候进行更新。
安东尼

5

除非我对这个问题有误解,否则我几乎总是使用$ this-> get_species,因为子类(在本例中为dog)可能会覆盖该方法,因为它确实对其进行了扩展。如果dog类没有重新定义该方法,则两种方法在功能上是等效的,但是如果将来您决定要在dog中使用get_species方法打印“ dog”,则必须返回所有代码并更改。

当您使用$ this时,它实际上是您创建的对象的一部分,因此也始终是最新的(如果使用的属性在对象的生存期内有所更改),而使用父类正在调用静态类方法。


如果我想覆盖该方法,那么使用$ this是一个好方法。谢谢
jerry 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.