【问题标题】:multiple ways of calling parent method in phpphp中调用父方法的多种方式
【发布时间】:2012-06-28 03:00:40
【问题描述】:

起初我很困惑为什么构造函数中的两个方法调用都有效,但现在我想我明白了。扩展类继承父类的方法,就好像它们在类本身中声明一样,并且这些方法存在于父类中,所以两者都应该工作。

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

对不起,我可能想多了。

abstract class Animal {

    function get_species() {

        echo "test";

    }

}

class Dog extends Animal {

    function __construct(){

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

    }

}

$spike = new Dog;

【问题讨论】:

    标签: php


    【解决方案1】:

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

    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();
    }
    

    同样,这使一切保持良好和一致,允许更改/修改本地方法,而不是依赖父方法。

    【讨论】:

    • 没有“扩展”我该怎么做?就像我在“人类”类中有一些“腿”,但我真的不需要扩展它,因为我不需要父母的“人类”功能。现在,如果我在human 中创建了一个$leg = new leg(),我将如何从腿部实例$leg 中调用人类的函数?
    • @user151496 腿不是人类的子类。一个人有很多条腿,但一条腿不是人的一种。因此你不应该有一个继承自人类的腿类,因为腿不是人类。
    • 你会让 Leg 成为一个有 Leggy 接口的类吗?或者只是让 Human 类实现 Leggy?我们如何才能最好地定义一条腿不仅是人类独有的,而且人类的腿是人类独有的,是人类的普遍属性?
    • paamayim nekudotayim 有点混乱。乍一看,您似乎在调用静态方法。它应该是 parent->get_species()
    • 同意。静态调用在许多方面都非常令人困惑。我应该在某个时候更新它。
    【解决方案2】:

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

    当您使用 $this 时,它实际上是您创建的对象的一部分,因此也始终是最新的(如果正在使用的属性在对象的生命周期中以某种方式发生了变化)而使用父类调用静态类方法。

    【讨论】:

    • 如果我想覆盖该方法,使用 $this 是一个很好的选择。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-06
    • 2013-09-09
    • 2021-11-16
    • 1970-01-01
    • 2016-02-14
    • 2015-11-06
    • 2012-10-08
    相关资源
    最近更新 更多