我有一个班级,$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()
函数来更改它。
答案 0 :(得分:4)
因为Third
没有自己的构造函数,所以它将从First
继承构造函数。继承在超类型和子类型之间创建行为关系。
因此,当您创建Third
的新实例时,该实例将具有'Karen'的$name
属性,但随后将调用继承的构造函数。这就是鲍勃的名字。如果您不希望子类型中存在该行为,则必须向Third
添加一个空构造函数,例如
class Third extends First
{
public function __construct()
{
// prevents parent First::__construct
}
}
另一种方法是删除ctor(或至少不在其中设置$name
)并将父级中的$name
属性预设为Bob。那么你最初的想法就可以了,例如。
class First
{
public $name = 'Bob';
}
class Third extends First
{
public $name = 'Karen';
}
请查看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 />";