PHP类中protected属性声明与构造函数实例化赋值的区别
二者作用完全不同,是配合关系而非替代关系
你写的两段代码是PHP面向对象语法里前后衔接的两个步骤,缺了任何一段代码都会出问题,具体差异和作用如下:
protected Carousel $carousel;的具体作用
这行是PHP 7.4版本后支持的类型化类属性声明,它本身不做任何赋值操作,只负责给类定义规则:
- 声明
FyStories类拥有一个名为$carousel的成员属性 - 限定属性的访问权限为
protected:仅当前类、当前类的子类可以直接读写这个属性,类外部无法直接访问 - 给属性加上强类型约束:这个属性只能存储
Carousel类(或其子类)的实例,如果后续赋值时传入字符串、数组、其他类实例等不符合类型的值,PHP会直接抛出类型错误,从语法层避免类型写错导致的隐性bug。
注意:这行代码不会自动给属性创建Carousel实例,如果只写这行不做后续赋值,访问这个属性时会直接触发「类型化属性访问前必须初始化」的致命错误。
构造函数内$this->carousel = new Carousel();的作用
这行是属性赋值操作,和前面的属性声明是配套的:它会在你每次new FyStories()实例的时候自动执行,给前面声明好的$carousel属性传入一个新建的Carousel实例,完成属性的初始化。
缺省任意一段代码的后果
- 删掉属性声明、只留构造函数赋值:PHP会动态创建一个
public权限的$carousel属性,没有任何类型约束,外部可以随意修改属性值,你后续代码不小心给这个属性赋错类型也不会提前报错;另外动态属性在PHP8.2版本已经被标记为废弃,更高版本会直接抛出错误。 - 删掉构造函数赋值、只留属性声明:实例化类后只要访问
$carousel属性就会报错,因为属性处于未初始化的状态。
补充:你可能见过类似
public function __construct(protected Carousel $carousel = new Carousel())的写法,这是PHP8引入的构造函数属性提升语法糖,本质就是把「属性声明」和「构造函数赋值」两步合并写在构造函数参数里了,底层执行逻辑和你分开写的版本完全一致。
内容的提问来源于stack exchange,提问作者user14541762
相关产品推荐
相关产品推荐

