102

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

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

对不起,我可能想多了。

abstract class Animal {

    function get_species() {

        echo "test";

    }

}

class Dog extends Animal {

    function __construct(){

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

    }

}

$spike = new Dog;
4

2 回答 2

138

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

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

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

于 2012-06-28T03:34:53.080 回答
7

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

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

于 2012-06-28T03:09:24.130 回答