构造函数属性提升(8.0)
本课属于 Coddy PHP 学习旅程的“面向对象编程”单元。第 42 课,共 91 课。
PHP 8.0 引入了构造函数属性提升,这项功能大幅减少了定义类时的样板代码。你不必单独声明属性,然后再在构造函数中赋值,而是可以一步完成这两件事。
这是你一直在使用的传统方法:
<?php
class Product {
private string $name;
private float $price;
public function __construct(string $name, float $price) {
$this->name = $name;
$this->price = $price;
}
public function getInfo(): string {
return $this->name . ": $" . $this->price;
}
}
使用构造函数属性提升时,你可以直接在构造函数参数前添加访问修饰符:
<?php
class Product {
public function __construct(
private string $name,
private float $price
) {}
public function getInfo(): string {
return $this->name . ": $" . $this->price;
}
}
$product = new Product("Laptop", 999.99);
echo $product->getInfo();
输出:
Laptop: $999.99在构造函数参数前添加 private、protected 或 public,PHP 就会自动创建属性并赋值。你可以在同一个构造函数中混用提升式参数和普通参数,也可以根据需要在构造函数体中添加逻辑。
要点:构造函数属性提升消除了重复的属性声明和赋值,让类更简洁、更易读,同时保留对封装的完全控制。
挑战
简单我们来构建一个联系人管理系统,展示构造函数属性提升的简洁之处。你将创建一个简洁、现代的 PHP 类,在保持良好封装的同时消除样板代码。
你将把代码分成两个文件:
Contact.php:创建一个Contact类,使用构造函数属性提升,直接在构造函数签名中定义所有属性。联系人应包含:- 一个私有的
$name属性(字符串) - 一个私有的
$email属性(字符串) - 一个私有的
$phone属性(字符串),默认值为"Not provided"
getFullDetails(),返回"[name] | [email] | [phone]"。再添加一个方法getSummary(),返回"Contact: [name]"。- 一个私有的
main.php:引入 Contact 文件。你会收到三个输入:姓名、电子邮箱和电话号码。创建两个Contact实例:- 第一个联系人使用全部三个值(姓名、电子邮箱和电话号码)
- 第二个联系人只使用姓名和电子邮箱(使用默认电话号码)
- 第一个联系人的完整详情
- 第一个联系人的摘要
- 第二个联系人的完整详情
- 第二个联系人的摘要
注意,构造函数属性提升让你可以在一个简洁易读的构造函数签名中定义属性、设置可见性、声明类型并赋值。带有默认值的可选电话号码参数表明,提升的参数可以像普通参数一样与默认值无缝配合。
亲手试试
<?php
require_once 'Contact.php';
// 读取输入
$name = trim(fgets(STDIN));
$email = trim(fgets(STDIN));
$phone = trim(fgets(STDIN));
// TODO: 使用全部 3 个值(姓名、邮箱、电话)创建第一个联系人
// TODO: 只使用姓名和邮箱创建第二个联系人(电话使用默认值)
// TODO: 打印第一个联系人的完整信息
// TODO: 打印第一个联系人的摘要
// TODO: 打印第二个联系人的完整信息
// TODO: 打印第二个联系人的摘要
?>这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: PHP 在线编译器