对不起,这似乎是一个初学者的问题。 如何在其扩展类中访问父类对象变量?
class FOO {
public $foo;
function __construct() {
$this->foo = 'string';
}
}
class Parent {
public $x;
function __construct() {
$this->x = new FOO();
var_dump($x); // this works
}
}
class Child extends Parent {
public $y;
function __construct() {
var_dump($this->x); // appears to be NULL all the time
}
}
如何正确传递$ x的值或引用?
答案 0 :(得分:8)
您的Child
类有自己的x
属性。儿童继承了所有不属于私人的内容,因此所有public
和protected
属性/方法都可用。
您声明了属性x
,但在调用Parent
构造函数之前,它尚未初始化。如果子类(在这种情况下为Child
)具有自己的构造函数,则会重写父构造函数,并且不会自动调用它
简而言之:您必须在子类中显式调用父构造函数:
class Child extends Parent
{
protected $y = 'Some string';//you can initialize properties here, too
//ALWAYS use access modifiers
public function __construct()
{
parent::__construct();//explicit call to parent constructor
var_dump($this->x);
}
}
请注意:如果父构造函数需要参数,那么子项必须执行相同的操作(签名必须匹配)。参数类型应该是兼容的(如果不是:存在违反合同的情况),并且您可能希望将参数传递给父构造函数,以便它也能完成它的工作。
让构造函数创建类内部需要的新实例被认为是不好的做法,BTW。 Google: SOLID ,请特别注意依赖注入和 Liskov原则,以及类型提示。
如果您仔细阅读材料,您就会明白为什么这是编写代码的更好方法:
class Dad
{
/**
* @var Foo
*/
protected $x = null;
public function __construct(Foo $foo)
{
$this->x = $foo;
}
}
//child
class Son extends Dad
{
/**
* @var string
*/
protected $y = 'Some string';
public function __construct(Foo $foo)
{
parent::__construct($foo);
}
public function test()
{
$results = array();
$results[] = '$this->x instanceof Foo ? '.($this->x instanceof Foo ? 'Of course!': 'No');
$results[] '$this instanceof Son ? '.($this instanceof Son ? 'Yup' : 'No?');
$results[] '$this instanceof Dad ? '.($this instanceof Dad ? 'Yes!' : 'No?');
return $results;//methods don't echo, they return...
}
}
$son = new Son(new Foo());
echo implode(PHP_EOL, $son->test());
此代码的输出将为
$this->x instanceof Foo ? Of Course!
$this instanceof Son ? Yup
$this instanceof Dad ? Yes!
这似乎让许多(相对)对OOP新的人感到困惑,但是子类与其父类的类型相同。如果你考虑一下,这是有道理的。对于外部世界(即,在给定类的实例上工作的代码),只有公共方法是可见的。根据定义,一个孩子继承了所有公开的东西,所以对外界来说,它并不重要。
如果某段代码需要Dad
个实例来执行某些操作,那么Son
也会起作用,因为Dad
提供的所有内容,Son
也可以提供。子类唯一能做的就是添加到父类已经提供的功能。
答案 1 :(得分:3)
您需要在Child的构造函数中调用Parent的构造函数,它不会自动调用:
class Child extends Parent {
public $y;
function __construct() {
parent::__construct();
var_dump($this->x); // appears to be NULL all the time
}
}
答案 2 :(得分:1)
正确的代码是:
<?php
error_reporting(E_ALL);
class FOO {
public $foo;
function __construct() {
$this->foo = 'string';
}
}
class Parents {
public $x;
function __construct() {
$this->x = new FOO();
var_dump($this->x); // fixed $x to $this->x
}
}
class Child extends Parents {
public $y;
function __construct() {
parent::__construct(); // you need to run Parents contructor
var_dump($this->x); // appears to be NULL all the time
}
}
$cl = new Child();
此外,您不能使用Parent
作为类名,但我相信您是手动编写此代码而未对其进行测试(我已将此代码中的Parent
类名称更改为{{1 }})