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

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

什么是"类"?------ 你的设计图纸

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

php 复制代码
// 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 关键字。

php 复制代码
$myRobot = new Robot(); // 造一个机器人

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

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

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

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

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

php 复制代码
// ✅ 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>)
php 复制代码
 // 假设 Robot 构造函数需要 name 和 age
 class Robot {
     public function __construct(string $name, int $age) { ... }
 }
// 正确传参方式
 $robot = new ('Rob' . 'ot')('小助手', 5);
对象的"引用"特性 ------ 一个机器人,多个遥控器

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

php 复制代码
$robot1 = new Robot();
$robot2 = $robot1; // $robot2 不是新机器人,而是指向 $robot1 的"遥控器"

$robot2->name = "小助手"; // 通过 $robot2 的遥控器改名字

echo $robot1->name; // 输出:小助手 ❗

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

继承:机器人升级 ------ extends

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

php 复制代码
class SuperRobot extends Robot { // SuperRobot 继承 Robot
    public $laser; // 新增激光武器

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

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

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

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

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

::class ------ 获取类的全名

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

php 复制代码
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 复制代码
// 自 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;
    }
}
相关推荐
枫叶梨花8 分钟前
使用Go语言获取Windows系统信息:从CPU到电池的全维度监控
开发语言·windows·golang
C_Liu_12 分钟前
从C语言到C++:拥抱面向对象编程的全新世界
c语言·开发语言·c++
哈基咩16 分钟前
Go 语言模糊测试 (Fuzz Testing) 深度解析与实践
开发语言·后端·golang
元气少女小圆丶17 分钟前
Mirror学习笔记
java·开发语言·学习
lly20240619 分钟前
Perl 面向对象编程深入解析
开发语言
瓦特what?25 分钟前
C + +
c语言·开发语言·c++·经验分享·笔记·算法·程序员创富
@十八子德月生26 分钟前
第三阶段—8天Python从入门到精通【itheima】-143节(pyspark实战——数据计算——flatmap方法)
大数据·开发语言·python·数据分析·pyspark·好好学习,天天向上·question answer
沐知全栈开发1 小时前
C# 运算符重载
开发语言
天机️灵韵1 小时前
开源医院信息管理系统:基于若依框架的智慧医疗解决方案
java·开发语言·spring boot·spring cloud·github·开源项目
啊阿狸不会拉杆1 小时前
《算法导论》第 1 章 - 算法在计算中的作用
开发语言·数据结构·c++·算法·排序算法