例如,两者之间有区别吗?一个比另一个更受欢迎吗?
Class Node{
public $parent = null;
public $right = null;
public $left = null;
function __construct($data){
$this->data = $data;
}
}
Class Node{
function __construct($data){
$this->data = $data;
$this->parent = null;
$this->left = null;
$this->right = null;
}
}
有一定的区别,是的:
#1:如果只在构造函数
中定义这些属性,则不正式地认为类具有这些属性的例子:
class Foo {
public $prop = null;
}
class Bar {
public function __construct() {
$this->prop = null;
}
}
var_dump(property_exists('Foo', 'prop')); // true
var_dump(property_exists('Bar', 'prop')); // false
$foo = new Foo;
$bar = new Bar;
var_dump(property_exists($foo, 'prop')); // true
var_dump(property_exists($bar, 'prop')); // true
除了不同的运行时行为,使用构造函数"添加"属性到你的类是不好的形式。如果您希望该类的所有对象都具有该属性(实际上应该一直如此),那么您也应该正式声明它们。虽然PHP允许您这样做,但这并不能成为随意设计类的借口。
#2:不能从构造函数外部初始化属性为非常量值
的例子:
class Foo {
public $prop = 'concatenated'.'strings'; // does not compile
}
关于此约束的更多示例在PHP手册中提供。
#3:对于在构造函数内部初始化的值,如果派生类省略调用父类构造函数,则结果可能是意外的
的例子:
class Base {
public $alwaysSet = 1;
public $notAlwaysSet;
public function __construct() {
$this->notAlwaysSet = 1;
}
}
class Derived extends Base {
public function __construct() {
// do not call parent::__construct()
}
}
$d = new Derived;
var_dump($d->alwaysSet); // 1
var_dump($d->notAlwaysSet); // NULL
我更喜欢在构造函数之外声明它们,原因如下:
- 保持我的构造器清洁
- 所以我可以正确地记录它们,添加类型信息和喜欢
- 所以我可以指定访问修饰符,使它们私有或受保护,但很少公开
- 因此,如果派生类不调用parent::__construct() ,它们也将被声明和/或初始化。
即使我需要将它们初始化为非常量值,我也会在构造函数外声明它们,并在构造函数中初始化它们。