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)

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

相关推荐
TlSfoward13 小时前
抓包代理链路下的 TLS 指纹变化分析 TLSFOWARD抓包工具
数据库·爬虫·网络协议·搜索引擎·php
—Miss. Z—16 小时前
计算机二级MySQL——简单应用题(存储过程&存储函数)
数据库·oracle·php
故乡de云17 小时前
AWS 添加付款方式失败排查清单:卡片、银行风控与账号状态逐项定位
开发语言·php
梦梦代码精18 小时前
基于ThinkPHP6 + Vue3的家政预约系统全解析:从LBS定位到自动派单的完整实现
java·docker·开源·php·代码规范
郑州光合科技余经理18 小时前
家政O2O平台解析:从0搭建上门预约小程序解决方案
android·java·开发语言·前端·小程序·架构·php
lxw184491251420 小时前
PHP后端(CI框架方向)面试题库,分为基础必问、MySQL、Redis、工程运维、高阶加分、场景实操六大模块,适配该JD全部考点,附带标准答案
ci/cd·面试·php
郑州光合科技余经理20 小时前
家政预约小程序后端源码深度剖析:支付回调实战
java·开发语言·前端·git·小程序·架构·php
weixin_408099671 天前
2026 图片去水印 API 接口完全指南:一键去除图片水印(附 Python/Java/PHP/C# 示例)
java·python·php·图片处理·api调用·图片去水印·石榴智能
王莎莎-MinerU2 天前
MCP 解决的是工具接入,科研 Agent 还缺的是科学证据接口标准化
开发语言·网络·人工智能·深度学习·pdf·c#·php
AC赳赳老秦2 天前
OpenClaw 采集任务日志审计:全程记录采集行为,满足合规溯源与企业审计要求
java·大数据·python·数据挖掘·数据分析·php·openclaw