为什么不能在子类中使用常量值覆盖父变量? (PHP)

时间:2012-02-13 08:26:49

标签: php oop inheritance

我有一个班级,$name设置为'bob'。在子课程中,我将$name设置为'Karen',但它不起作用。

在我的回声中,第一个说“bob”而不是'Karen'。第二个,使用子类方法,虽然有效。

为什么会出现这种情况?

class First {

    public $name;

    public function __construct() {

        $this->name = 'bob';
    }
}

class Third extends First {

    public $name = 'Karen';
    public function set_name ($name) {
        $this->name = $name;
    }
}

$instance_of_third = new Third;
$third_name = $instance_of_third->name;

echo "<br />We're looking for Karen: $third_name<br />";
// $third_name here is 'bob' from parent class

$instance_of_third->set_name("Karen");
$third_name = $instance_of_third->name;
// $third_name here is 'Karen' only after using set_name()
echo "<br />We're looking for Karen: $third_name<br />";

编辑:我添加了两行显示输出的确切内容。

即使$name在子类中明确设置为'Karen',它也会显示为'bob',除非使用set_name()函数来更改它。

6 个答案:

答案 0 :(得分:4)

因为Third没有自己的构造函数,所以它将从First继承构造函数。继承在超类型和子类型之间创建行为关系。

因此,当您创建Third的新实例时,该实例将具有'Karen'的$name属性,但随后将调用继承的构造函数。这就是鲍勃的名字。如果您不希望子类型中存在该行为,则必须向Third添加一个空构造函数,例如

class Third extends First
{
    public function __construct()
    {
        // prevents parent First::__construct
    }
}

demo

另一种方法是删除ctor(或至少不在其中设置$name)并将父级中的$name属性预设为Bob。那么你最初的想法就可以了,例如。

class First
{
    public $name = 'Bob';
}

class Third extends First
{
    public $name = 'Karen';
}

demo

请查看PHP手册中的继承和可见性章节:

答案 1 :(得分:1)

创建类的对象时,将调用构造函数。

因此,父类的构造函数在你的情况下编写了$ name的值。

答案 2 :(得分:1)

因为在初始化字段之后调用构造函数,所以它会覆盖$ name字段。

答案 3 :(得分:1)

构造函数会覆盖默认值。 (通常因为它是在默认值实例化之后调用的),更健壮的方式就是这样:

class First {
    public $name;
    public function __construct($name) {
        $this->name = $name;
    }
}

然后通过以下方式调用它:

$first_instance = new First("Bob");

它也将扩展到Third类。

答案 4 :(得分:0)

口译员很可能从上到下阅读,就像我们一样。

在第一个示例中,您将公共变量设置为Karen,但是由于子类继承了第一个类的构造函数,因此将设置“Bob”。

答案 5 :(得分:0)

尝试将$ name声明为静态。并通过Third :: $ name访问它。例如。

class First {

    public static $name;

    public function __construct() {

        self::$name = 'bob';
    }

    // edit late static binding
    public function getName() {
       return static::$name;
    }


}

class Third extends First {

    public static $name = 'karen';

}

$instance_of_third = new Third();
//$third_name = $instance_of_third::$name;
$third_name = $instance_of_third->getName();    

echo "<br />We're looking for Karen: $third_name<br />";
相关问题