【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;
    }
}
相关推荐
ServBay7 小时前
垃圾堆里编码?真的不要怪 PHP 不行
后端·php
用户9623779544810 小时前
CTF 伪协议
php
BingoGo3 天前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php
JaguarJack3 天前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php·服务端
BingoGo4 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php
JaguarJack4 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php·服务端
JaguarJack5 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
后端·php·服务端
BingoGo5 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
php
JaguarJack6 天前
告别 Laravel 缓慢的 Blade!Livewire Blaze 来了,为你的 Laravel 性能提速
后端·php·laravel
郑州光合科技余经理6 天前
代码展示:PHP搭建海外版外卖系统源码解析
java·开发语言·前端·后端·系统架构·uni-app·php