Php 从类A的类B(扩展类A)调用静态方法

Php 从类A的类B(扩展类A)调用静态方法,php,oop,Php,Oop,在一次练习测试中,有一个有趣的问题,我不明白答案。以下代码的输出是什么: <?php class Foo { public $name = 'Andrew'; public function getName() { echo $this->name; } } class Bar extends Foo { public $name = 'John'; public function getName() {

在一次练习测试中,有一个有趣的问题,我不明白答案。以下代码的输出是什么:

<?php
class Foo {
    public $name = 'Andrew';

    public function getName() {
        echo $this->name;
    }
}

class Bar extends Foo {
    public $name = 'John';

    public function getName() {
        Foo::getName();
    }
}

$a = new Bar;
$a->getName();
?>

起初,我认为这是一个错误,因为静态方法不能引用$this(至少在PHP5中)。我自己测试了这个,它实际上输出了John

我添加了Foo::getName();在脚本的最后,我得到了我所期望的错误。那么,当你从一个扩展了你所调用的类的类中调用一个静态方法时,会发生什么变化呢


有人介意详细解释一下这里到底发生了什么吗?

如果调用绑定到另一个对象的静态方法,该方法将在当前对象的上下文中执行。它允许访问$this对象

从子类内部调用超类方法的更好方法是:

parent::getName();

$this指向在其上下文中调用该方法的对象。所以:$这是$a->getName()是$a$$fooInstance->getName()中的这个将是$fooInstance。在设置了$this(在对象$a的方法调用中)并且我们调用了静态方法的情况下,$this仍然被分配给$a


使用此功能可能会带来很多困惑。:)

当您调用
$a->getName()
时,您正在引用一个特定的对象,
$a
,它属于
Bar
类,因此返回“John”

Foo::getName()
在函数外部无效,因为没有特定的对象

我不确定它在PHP中是否有效,但是如果您
(Foo)$a->getName()
那样将对象强制转换为超类,那么您将得到“Andrew”作为结果。您仍然在谈论特定对象(
$a
),但在本例中是类型
Foo
。(请注意,您通常不希望这样做)

在PHP5中,您将使用::getName()代替

如果您希望扩展而不是完全重写基类的行为,那么它非常有用,例如,这可能会使它更清晰

class Bar extends Foo {
    public $name = 'John';

    public function getName() {
        echo "My name is ";
        parent::getName();
    }
}

有时程序员更擅长用代码解释事情,而不是用英语

这里发生的第一件事是重载的概念。当您实例化Bar时,它的getName()方法重载Foo中同名的方法

重载是OOD的一个强大而重要的部分

但是,能够调用父类(Foo)中存在的方法的版本通常很有用

下面是一个例子:

class Dog
{
   public function getTag()
   {
      return "I'm a dog.";
   }
}

class Skip extends dog
{
   public function getTag()
   {
      return Dog::getTag() . " My name is Skip.";
      // I'm using Dog:: because it matches your example. However, you should use parent:: instead.
   }
}

$o = new Skip();
echo $o->getTag(); // Echo's: "I'm a dog. My name is Skip."
显然,这是一个非常狭隘的例子,但它说明了一点

基类是类型的最通用实现。在本例中,它是“Dog”。您希望将信息放在该基类中,该基类对该类型的所有实例都是通用的。这可以防止每个派生类中的重复(如“Skip”)


您的脚本可能无意中利用了此功能

PHP中有super::符号吗?我唯一能想到的是静态类的parent::for。