类中的变量

时间:2011-09-23 05:09:18

标签: php

我偶然发现了一个非常有线的错误:

class A {
     public $var = "test";
     public function __construct() {
        $this->var = "test2";
        $b = new B;
        $b->method();
    }
}

class B extends A {
    public function method() {
        $c = new C;
        $c->method();
    }
}

class C extends B {
    public function method() {
        echo $this->var;
    }
}

$a = new A;

我得到输出“test”,但我不知道为什么,因为变量var应该在A类中被覆盖。

如果我在A类中输出$ var,则表示“test2”,如果我在B类中输出它,则说“test”......

1 个答案:

答案 0 :(得分:2)

由于循环引用(例如:$b = new B的构造函数中的A),您问题上的代码将无效,这将导致PHP耗尽内存。你真的不应该在父类中实例化子类。

话虽如此,通过你所描述的内容,听起来你正在B中定义一个构造函数,它会覆盖父构造函数。在PHP中,子类不会隐式调用父构造函数(与Java之类的语言不同)。

因此,它只是继承了$var的原始值(即:"test"),它永远不会改变。如果您在__construct()中覆盖B,则必须显式调用父构造函数,例如:

class B extends A {
    public function __construct() {
        parent::__construct();
    }
}

当您执行以下操作时,这应该会给您"test2"

$b = new B;
echo $b->var;

请参阅此演示:http://ideone.com/Q9Bp8


  

有3个类的最佳方法是什么,第三个和第二个类可以访问第一个类的变量?

答案是,这取决于你在做什么。听起来你并不了解OOP是如何工作的,这是一个更大的问题。通常,只有当子类可以重用父类中的代码和/或存在某种is-a或has-a关系时,才使用继承。

如果您的类不适合此模型,只需使3个类独立,并保持对其他类中第一个类的引用。例如:

class A {
    public $n = 0;
    public function change($n) {
        $this->n = $n;
    }
}

class B {
    public function __construct($a) {
        $this->my_a = $a;
    }

    public function get() {
        return $this->my_a->n;
    }
}

$a = new A();
$b = new B($a):

echo $b->get();  // 0
$a->change(10);
echo $b->get();  // 10

请参阅此演示:http://codepad.org/xL1Dzs0W