当前位置: 首页 > web >正文

【PHP类的基础概念:从零开始学面向对象】

《PHP类的基础概念:从零开始学面向对象》

什么是“类”?—— 你的设计图纸

想象你要开一家机器人制造工厂。你需要一张“设计图纸”,上面画着机器人该有什么“部件”(比如名字、型号)和“功能”(比如行走、说话)。在 PHP 里, “类”(Class)就是这张设计图纸

// Robot 类:机器人设计图纸
class Robot {// ... 在这里定义部件和功能
}

类本身不是机器人,它是制造机器人的模板

类里有什么?—— 你的三大法宝

一张完整的图纸包含三样东西:

  1. 常量 (Constants)固定不变的设定。

    • const MAX_SPEED = 100; // 所有机器人的最高速度上限
    • 一旦定义,永远不能改变。
  2. 属性 (Properties) :机器人的“部件”或“特征”。

    • public $name; // 机器人的名字
    • public $color; // 机器人的颜色
    • 属性是机器人的“身份证信息”。
  3. 方法 (Methods) :机器人的“功能”或“动作”。

    • public function walk() { ... } // 机器人走路的功能
    • public function speak($words) { ... } // 机器人说话的功能
    • 方法是机器人的“技能包”。

📌 重要提示:在方法内部定义的变量(如 function walk() { $step = 1; } 中的 $step)是局部变量,只在该方法执行时存在,用完就消失,它不是类结构的一部分。

创建机器人(实例化)—— 用图纸造机器

有了图纸,就可以造机器人了!这叫“实例化”。使用 new 关键字。

$myRobot = new Robot(); // 造一个机器人

$myRobot 就是根据 Robot 类创造出来的具体机器人,我们称之为“对象”或“实例”。

new 操作符的进化:PHP 8.0+ 的任意表达式支持

在 PHP 8.0 之前,new 后面只能跟固定的类名

// PHP 8.0 之前
$className = 'Robot';
$instance = new $className(); // 需要变量,写法稍显别扭

从 PHP 8.0.0 起,new 可以用在任意表达式中,这带来了巨大的灵活性和简洁性!

// ✅ PHP 8.0+ 新写法:直接在表达式中使用 new// 1. 从函数返回类名
function getRobotClass(): string {return 'Robot';
}
$robot1 = new (getRobotClass());// 2. 字符串拼接
$robot2 = new ('Rob' . 'ot');// 3. 使用 ::class 常量
class AdvancedRobot {}
$robot3 = new (AdvancedRobot::class);// 4. 创建后立即调用方法
echo (new DateTime())->format('Y-m-d'); // 创建 DateTime 对象并调用 format
// 注意:从 PHP 8.4 起,括号 ( ) 可以省略:echo new DateTime()->format('Y-m-d');

💡 关键点

  • new ($className) 这种写法在 PHP 8.1+ 被标记为“软弃用”,强烈推荐使用 new ($expression) 的新语法
  • 给构造函数传参:如果类有构造函数需要参数,直接在表达式后的括号里传入即可:new (<expression>)(<arg1>, <arg2>)
 // 假设 Robot 构造函数需要 name 和 ageclass Robot {public function __construct(string $name, int $age) { ... }}
// 正确传参方式$robot = new ('Rob' . 'ot')('小助手', 5);
对象的“引用”特性 —— 一个机器人,多个遥控器

记住核心规则:对象变量默认是“引用” ,而不是“值”。

$robot1 = new Robot();
$robot2 = $robot1; // $robot2 不是新机器人,而是指向 $robot1 的“遥控器”$robot2->name = "小助手"; // 通过 $robot2 的遥控器改名字echo $robot1->name; // 输出:小助手 ❗

为什么? 因为 $robot1$robot2 指向的是同一个机器人实体。改一个,另一个也跟着变。

继承:机器人升级 —— extends

PHP 支持“机器人升级”。新机器人可以继承旧机器人的所有部件和功能,然后添加自己的新东西。

class SuperRobot extends Robot { // SuperRobot 继承 Robotpublic $laser; // 新增激光武器public function fly() { // 新增飞行功能echo "起飞!";}
}
  • extends 表示继承。
  • 重要限制:PHP 不支持多重继承,一个机器人只能有一个“爸爸”(基类)。
覆盖 (Override) 与 Final

新机器人可以改进旧功能。

class SuperRobot extends Robot {// 覆盖父类的 speak 方法public function speak($words) {echo "超级机器人说:" . $words;}
}
  • 覆盖规则 (LSP - 里氏替换原则)

    • 方法签名(参数)必须兼容。不能删除父类方法的必需参数。
    • 可以增加可选参数。
    • 不能收紧访问权限(比如父类 public,子类不能改成 private)。
  • 覆盖的例外

    • 构造函数 (__construct) :子类构造函数的签名不需要与父类兼容。子类可以有自己独立的参数列表(但仍需通过 parent::__construct() 调用父类构造函数来初始化父类部分)。
    • private 方法:子类可以定义一个与父类 private 方法同名的方法,但这不是覆盖,而是完全独立的方法,因为 private 方法在子类中不可见。
  • Final 关键字:如果父类方法或常量被标记为 final,子类绝对不能覆盖它,这是“最终设定”。

::class —— 获取类的全名

需要知道一个类的完整名称(尤其带命名空间时)?用 ::class

namespace Factory\Robots;class WorkerRobot {}echo WorkerRobot::class; // 输出: Factory\Robots\WorkerRobot// 对象也可以用 (PHP 8.0+)
$robot = new WorkerRobot();
echo $robot::class; // 输出: Factory\Robots\WorkerRobot
Nullsafe 操作符 ?-> —— 安全调用

不确定机器人是否存在或有某个功能?用 ?-> 安全调用。

// 自 PHP 8.0.0 起可用
$result = $repository?->getUser(5)?->name;// 上边那行代码等价于以下代码
if (is_null($repository)) {$result = null;
} else {$user = $repository->getUser(5);if (is_null($user)) {$result = null;} else {$result = $user->name;}
}
http://www.xdnf.cn/news/16817.html

相关文章:

  • ES11 / ES2020 动态 import()(异步加载模块)
  • Java项目:基于SSM框架实现的小区物业管理系统【ssm+B/S架构+源码+数据库+毕业论文+开题报告+任务书+远程部署】
  • 使用神经网络与5折交叉验证进行基因组预测:基础知识指南
  • 【JMeter】性能测试脚本录制及完善
  • 从一开始的网络攻防(十三):WAF入门到上手
  • day 40 打卡-装饰器
  • 【JEECG】JVxeTable表格拖拽排序功能
  • [SKE]Python gmssl库的C绑定
  • 机器视觉halcon7-缺陷检测
  • 计算机网络1-3:三种交换方式
  • 开源 Arkts 鸿蒙应用 开发(十二)传感器的使用
  • 双线串行的 “跨界对话”:I2C 与 MDIO 的异同解析
  • 数学建模——最大最小化模型
  • 硬件电路设计(基本元器件)
  • sqli-labs:Less-7关卡详细解析
  • 数据治理平台如何选?深度解析国产化全栈方案与行业落地实践
  • Charles中文教程 高效抓包与API接口调试实战全指南
  • 《汇编语言:基于X86处理器》第10章 复习题和练习
  • yolo8+阿里千问图片理解(华为简易版小艺看世界)
  • Docker常用命令速查手册:容器运维七维指南
  • Centos7 | 防火墙(firewalld)使用ipset管理ip地址的集合
  • 以ros的docker镜像为例,探讨docker镜像的使用
  • Power Pivot 数据分析表达式(DAX)
  • 《Java 程序设计》第 10 章 - 接口与 Lambda 表达式
  • HTML基础P2 | JS基础讲解
  • JSON.parse解析大整数踩坑
  • 重生之我在10天内卷赢C++ - DAY 1
  • 安全和AI方向的学习路线
  • Tdesign-React 模板面包屑如何放到 Header头部
  • 白话容器基础(一):进程