PHP继承,父函数使用子变量

时间:2012-03-15 19:47:35

标签: php oop inheritance

在查看一些PHP代码时,我发现了一件奇怪的事情。以下是它的简单示例说明:

文件A.php:

<?php
class A{
    public function methodA(){
        echo $this->B;
    }
}
?>

文件B.php:

<?php
    class B extends A{
        public $B = "It's working!";
    }
?>

文件test.php:

<?php
    require_once("A.php");
    require_once("B.php");
    $b = new B();
    $b->methodA();
?>

运行test.php打印出“它正在工作!”,但问题是它为什么有效? :)这是一个功能还是一个bug?类A中的方法方法A也可以调用类B中的方法,这些方法不应该在OOP中工作。

8 个答案:

答案 0 :(得分:12)

您只是实例化了课程B。暂时忽略A,并假装methodA()是课程B的一部分。

当课程B延伸A时,它会获得所有A的功能。在代码运行之前,不评估$this->B,而不是之前。因此,不会发生错误,并且在$this->B类中存在B时不会发生错误。

答案 1 :(得分:6)

PHP是一种动态语言。方法和数据成员在运行时进行评估。当您调用方法或访问成员时,PHP实际上会查找排序的哈希表,以确定是否可以在此对象上访问此方法或成员,这可以是继承层次结构中的任何位置。

不仅仅是继承,你总是可以在运行时将任意数据分配给一个对象,而且类中的代码仍然可以使用$ this-&gt;这样的东西来访问它,其中'某些东西'甚至不存在于课堂上

答案 2 :(得分:3)

$this只是一个对象变量 - 一个特殊的变量,因为它是当前变量,但它仍然只是一个对象变量。

因为$B::B是一个公共成员变量,所以可以从任何地方访问B实例的引用,例如用对象变量。

随着公共成员随处可访问,任何功能,甚至可以从A::methodA()内访问。

所以实际上并不奇怪。示例中的类继承仅涉及在调用$this时以A::methodA()“参数”的形式传递对象变量的(不可见)。

请参阅以下示例,该示例可能使其更加明显:

function methodA($object) {
    echo $object->B;
}

class B {
    public $B = "It's working!";
    public function methodA() {
        methodA($this);
    }
}

答案 3 :(得分:2)

由于PHP是一种动态语言,因此调用正在使用它的实例上可能存在的属性或方法没有任何问题(在本例中是子类B的实例)

答案 4 :(得分:1)

PHP是一种动态语言。当在B的实例上调用methodA()时,B的成员$ B确实存在。

$a = new A();
$a->methodA();

无效。

在某些动态语言中,您甚至可以在运行时定义方法。

答案 5 :(得分:1)

这对我有意义;由于出现在B类中,因此$ B在结果对象中可用。因为$ this-&gt; B在运行时被计算,并且在此之前设置了值(当实例化B类时),它被发现设置正确。

您也可以使用方法执行此操作,因为它们的存在在执行之前不会被检查(尽管通常在方法的情况下在父类中声明它们是抽象的,因此强制子项实现它们)。

答案 6 :(得分:1)

这就是OOP的工作方式。起初看起来有点奇怪,因为您认为A必须首先知道$this->B是什么(实际上在某些语言中这会产生编译器警告),但行为是正确的,因为子类你正在使用的是定义你的函数正在寻找的变量。如果您从methodA()的实例调用A(),则会出现“未定义”错误。

现在,奇怪的是(读:错误),如果 THIS 有效:

class A {
   public $b = "Derp";
}
class B extends A {
  function sayIt() { echo $this->b; }
}
$a = new A();
$a->sayIt();

答案 7 :(得分:0)

B类从A类扩展,因此它继承了A类中的方法methodA()