PHP 抽象类完全指南(含 PHP 8.4 新特性)

PHP 抽象类完全指南(含 PHP 8.4 新特性)

------ 用"合同"和"模板"来理解抽象机制

本文用"公司制度""合同条款"等比喻,帮你彻底理解抽象类、抽象方法、抽象属性,适合复习和深入掌握。


一、什么是"抽象类"?------ 它是个"模板",不是"实体"

🧩 比喻:公司总部的"制度模板"

想象你是一家连锁店的总部,你不能直接"开店",但你可以制定一套 开店模板

  • 必须有店名
  • 必须有营业时间
  • 必须实现"开门""关门"动作

这个"模板"就是 抽象类(abstract class)

csharp 复制代码
abstract class 店铺 {
    // 这个类不能直接 new!
    // 它只是一个"模板"
}

抽象类不能被实例化 (不能 new),只能被继承。


二、抽象方法:只规定"做什么",不管"怎么做"

📝 比喻:合同里的"必须做的事"

总部规定:每家分店必须实现"开门"和"关门":

php 复制代码
abstract class 店铺 {
    // 只写"要做什么",不写"怎么做"
    abstract public function 开门();
    abstract public function 关门();
}

🔑 抽象方法的特点

  • 没有 {} 花括号,没有实现
  • 必须是 publicprotected
  • 子类必须实现它

✅ 子类必须"履约":

scala 复制代码
class 咖啡店 extends 店铺 {
    public function 开门() {
        echo "打开咖啡机,播放音乐\n";
    }
    public function 关门() {
        echo "关闭设备,锁门\n";
    }
}

❌ 如果你不实现 开门(),PHP 会报错:

csharp 复制代码
Class 咖啡店 contains abstract method 开门 and must therefore be abstract

三、PHP 8.4 新特性:抽象属性(abstract properties)

这是 PHP 8.4 最大的新功能之一!

🎯 问题来了:以前只能抽象"方法",不能抽象"属性"

以前你只能规定"要有开门动作",但不能规定"必须有店名"。

现在可以了!


📌 抽象属性:规定"必须有某个属性",并可要求"如何读写"

比喻:合同里规定"每家店必须有店名,并且只能读不能改"
csharp 复制代码
abstract class 店铺 {
    // 新语法!PHP 8.4
    abstract public string $店名;

    abstract protected int $编号;
}

✅ 含义:

  • 所有继承 店铺 的子类,必须有一个 public string $店名
  • 必须有一个 protected int $编号

✅ 子类必须"提供"这些属性

scala 复制代码
class 咖啡店 extends 店铺 {
    public string $店名 = "星巴克";
    protected int $编号 = 1001;
    
    // ✅ 满足了抽象属性的要求
}

❌ 如果你不写 $店名,PHP 会报错!


四、更高级:抽象属性可以要求"读"或"写"行为

🎯 场景:我想规定"$价格 可以读,但不能改"(只读),或者"$销量 只能改,不能看"(只写)

PHP 8.4 支持用 get/set 要求 来定义抽象属性。

csharp 复制代码
abstract class 商品 {
    // 要求子类提供一个"可读"的 $价格
    abstract public readonly float $价格;

    // 要求子类提供一个"可写"的 $折扣(但不关心能不能读)
    abstract public writeonly float $折扣;

    // 要求子类提供一个完整的 $库存(可读可写)
    abstract public int $库存;
}

✅ 子类可以用多种方式"履约"

scala 复制代码
class 咖啡 extends 商品 {
    // ✅ 用普通属性满足"只读价格"
    public readonly float $价格 = 30.0;

    // ✅ 用普通属性满足"只写折扣"
    private float $折扣内部;
    public writeonly float $折扣 {
        set { $this->折扣内部 = $value; }
    }

    // ✅ 用完整属性满足"库存"
    public int $库存 = 100;
}

✅ 也可以用"挂钩属性"(用 get/set 块)来实现。


五、protected 抽象属性的灵活性

📌 规则:

protected 抽象属性,可以用 protectedpublic 属性来满足。

scala 复制代码
abstract class 父类 {
    abstract protected string $秘密;
}

class 子类 extends 父类 {
    public string $秘密 = "我是公开的秘密"; // ✅ 允许!
}

✅ 为什么允许?

  • publicprotected 更开放,满足"至少能被子类访问"的要求。
  • 但反过来不行:不能用 private 满足 protected

六、抽象类中可以有"具体实现"吗?

可以! 抽象类不是"全抽象",它是"混合体"。

php 复制代码
abstract class 店铺 {
    abstract public string $店名;

    // ✅ 可以有具体方法(普通方法)
    public function 打印信息() {
        echo "欢迎光临{$this->店名}!\n";
    }

    // ✅ 可以有普通属性
    protected int $访客数 = 0;

    abstract public function 开门();
}

🔑 抽象类 = 抽象 + 具体 的混合体,像个"半成品模板"。


七、总结:一张表讲清抽象机制

类型 语法 子类必须实现? 说明
抽象类 abstract class A ❌ 不能实例化 只能被继承
抽象方法 abstract public function foo(); ✅ 必须实现 无方法体
抽象属性 abstract public string $name; ✅ 必须提供 PHP 8.4 新增
只读抽象属性 abstract public readonly int $id; 要求属性可读
只写抽象属性 abstract public writeonly float $discount; 要求属性可写

✅ 生活化口诀(终极记忆法)

"抽象类 = 合同模板"
"抽象方法 = 必须做的事"
"抽象属性 = 必须有的东西"
"谁继承,谁履约;少一样,就报错!"


📚 一句话回答你的问题

"抽象属性 "是 PHP 8.4 的新功能,它允许你在一个抽象类中声明某个属性必须存在 ,并可以规定它是 public 还是 protected,甚至可以要求它是 只读(readonly)只写(writeonly)

子类必须用标准属性挂钩属性来"满足"这些要求,就像"履约"一样。

相关推荐
zh731412 分钟前
laravel在cli模式下输出格式漂亮一些
microsoft·php·laravel
onejason1 小时前
《PHP 爬虫实战指南:获取淘宝店铺详情》
前端·后端·php
用户3074596982076 小时前
📘 PHP 继承与静态机制深度解析
php
卑微的小鬼6 小时前
TCP如何实现可靠传输?实现细节?
网络·tcp/ip·php
wuzuyu36510 小时前
Laravel The requested URL /hellowzy was not found on this server. 404 问题的解决
php·laravel
kebeiovo11 小时前
网络muduo库的实现(2)
服务器·网络·php
七七软件开发12 小时前
二手交易 app 系统架构分析
java·python·小程序·系统架构·php
七七软件开发1 天前
直播 app 系统架构分析
java·python·小程序·系统架构·php
linux修理工1 天前
使用 SecureCRT 连接华为 eNSP 模拟器的方法
服务器·开发语言·php