滚动新闻 →
唐玄宗时代为何从盛世走向动荡 “考上就是云南王” 昆明一事业编岗位九千人报名 卡车冲入堪萨斯足球赛场酿2死10伤 女司机遭拘留 预算有限旧房最值得优先改善哪些地方 腐乳为什么会成为中国传统食品 加拿大陆军基地突发爆炸大火 伤亡人数未明 “赤马重阳”60年一遇 做4件事避灾祈福 九月的秋风吹过加拿大贾斯珀国家公园,湖光与雪山正好相遇 起动机转动无力应该检查哪些部件 贵州救援队吊车时车辆坠落 司机被砸身亡 佛山“水蟑螂蛋塔”走红 意大利人也慕名而来 纽约曼哈顿地铁站枪击案酿1死 嫌犯疑穿红帽T逃离 固态电池距离普通消费者还有多远 北美买房为什么不能只看首付款 生活在北美如何制定适合自己的储蓄计划 北美豪华游艇购买需要准备多少预算 休斯顿全侨庆祝中华民国115年国庆晚宴 贵宾云集 因“六四”被整肃的五名中共高官 进化骗局(31) 非洲猿人造假序幕 一周经济回顾:中国真有14亿人口? 制片人怎样判断一个演员到底值多少钱 加拿大报税后发现银行账户填错怎么办 殖民时代法院如何处理债务纠纷 黑脚人控制的北美西部世界 亲共侨领宣国军申请免保释金 遭法官驳回 观美国两党竞争 中国人从中学到什么? 美海关公布年终执法 查获724公斤冰毒 纱窗应该怎么测量尺寸 AI 模型版本管理应该怎样设计,训练完成后的模型如何安全进入生产环境 美议员提案:H-1B薪资从六万升至十四万美元 Cloud SQL 高可用怎么配置,数据库发生实例故障后如何恢复服务 PHP 更新数据时加入 version 字段,可以解决哪些并发问题 57个粉丝的博主发AI视频调侃问界 被索赔百万 笔记本电脑插电才能开机,拔掉充电器马上关机,电池可能出了什么问题 Windows 11 文件分组功能怎么用?让大量文件更加容易浏览 PHP PDO 预处理语句怎么写?从查询参数到安全执行完整演示 辛弃疾为什么能够把豪情写进词里 骗子被耍惨 澳洲初创公司用AI扮受害者收集情报 浙江男没工作杀人泄愤 进写字楼随机砍死女职员 枸杞在中国传统饮食文化中的历史

PHP 类和对象怎么理解?从简单实例进入面向对象编程

发布时间: 2026-09-27 03:00:02    最后更新: 2026-10-17 00:27:26    阅读:65  约12 分钟阅读     

PHP 类和对象怎么理解?从简单实例进入面向对象编程
图片说明:示意图   图片来源:Public Domain(公有领域)
如果刚开始学习 PHP 面向对象编程,很多人都会被“类、对象、属性、方法、实例化、封装、继承、多态”这一串术语绕进去。看起来每个词都不难,放在一起却很容易变成一锅概念粥。 其实,理解 PHP 的类和对象并不需要从复杂的设计模式开始。先搞清楚一个问题就够了:当程序不再只是处理几行数据,而是需要长期管理某种状态,并围绕这些状态提供一组操作时,怎样让代码保持清晰? 类和对象就是解决这类问题的一种组织方式。 例如,一个汽车管理程序可能需要保存汽车品牌、型号和颜色,同时还需要提供启动、停车、修改状态等操作。如果所有数据都散落在数组和变量中,代码规模一大,就容易出现“这个变量属于哪辆车”“这个函数修改的是哪份数据”之类的问题。 PHP 可以把相关的数据和操作组织到一个类中: class Car { public string $brand = 'Toyota'; public string $model = 'Corolla'; public string $color = 'Blue'; public function startEngine(): void { echo "Engine started."; } } 这里的 Car 是一个类。它描述了这一类对象具有哪些属性,以及可以执行哪些操作。 当程序执行: $myCar = new Car(); new 会创建一个 Car 类的对象,并把这个对象的引用赋给 $myCar。此后可以通过对象访问公开属性和方法: echo $myCar->brand; $myCar->startEngine(); 初学者可以暂时把类理解成一种结构定义,把对象理解成根据这个结构创建出来的具体实例。不过,这个比喻只能帮助入门。类并不是一张简单的“现实世界模板”,对象也不是把所有方法复制到某个变量里面。PHP 对象是运行时的数据结构,方法属于类的方法定义,对象保存自己的实例状态。 这个区别在程序变复杂以后非常重要。 例如: $car1 = new Car(); $car2 = new Car(); $car1->color = 'Red'; $car2->color = 'Black'; 这里有两个不同的对象。它们来自同一个 Car 类,因此具有相同的属性和方法定义,但每个对象可以拥有自己的属性值。 这就是对象的重要意义之一:代码可以同时管理多个相互独立的状态,而不需要为每一份数据重新写一套函数。 另一个核心概念是访问控制。 PHP 提供了 public、protected 和 private 等访问修饰符。public 表示外部代码可以访问,private 表示只能在声明它的类内部访问,protected 则允许声明它的类以及继承体系中的相关类访问。 比如银行账户的余额通常不应该允许外部代码随便修改: class BankAccount { private float $balance = 0; public function deposit(float $amount): void { if ($amount <= 0) { throw new InvalidArgumentException('Amount must be positive.'); } $this->balance += $amount; } public function getBalance(): float { return $this->balance; } } 外部代码不能直接执行: $account->balance = -100000; 因为 $balance 是 private。 如果需要增加余额,就应该通过 deposit() 这样的公开方法完成。这样做的意义并不只是“保护变量”,更重要的是把修改状态的规则集中起来。 这就是封装。 封装并不意味着所有属性都必须设置成 private,然后机械地为每个属性生成一个 getter 和 setter。真正有价值的封装,是让对象负责维护自己的有效状态,并控制哪些操作可以从外部进行。 构造函数也是理解对象生命周期时非常重要的一环。 例如用户对象: class User { private string $username; private string $email; private string $passwordHash; public function __construct( string $username, string $email, string $password ) { $this->username = $username; $this->email = $email; $this->passwordHash = password_hash( $password, PASSWORD_DEFAULT ); } public function login(string $inputPassword): bool { return password_verify( $inputPassword, $this->passwordHash ); } } 这里的 __construct() 是 PHP 的构造方法。执行: $user = new User( 'john', 'john@example.com', 'secret123' ); 创建对象时,构造方法会自动执行。 密码也没有直接保存为明文,而是通过 password_hash() 生成密码哈希。登录时再使用 password_verify() 检查用户输入的密码是否匹配。 这里可以看到类和对象真正有用的一面:User 不只是保存三个字段,它还可以负责与这些状态直接相关的行为。 不过,这并不意味着所有业务逻辑都应该塞进 User 类。 例如发送邮件、处理支付、调用第三方 API、生成报表等工作,如果全部塞进 User 类,最后很可能得到一个几百行甚至上千行的“万能 User”。这种设计看起来很面向对象,实际上只是把混乱从函数搬进了类。 大型 PHP 应用通常会把不同职责拆开。例如 Product 可以负责商品自身的数据和规则,Order 负责订单状态,PaymentService 负责支付流程,MailService 负责邮件发送,Repository 负责数据访问。 这时候,面向对象编程的价值就从“把变量放进 class”进一步变成了“划分职责”。 PHP 的继承也是面向对象编程的重要机制。例如: class Animal { public function speak(): string { return 'Some sound'; } } class Dog extends Animal { public function speak(): string { return 'Woof'; } } Dog 通过 extends 继承了 Animal,同时可以重新定义 speak()。 但继承并不是代码复用的万能按钮。现代 PHP 项目中,很多情况下组合和接口比深层继承更加灵活。例如程序真正关心的可能不是“这个对象是不是某个父类的子类”,而是“这个对象是否提供某种能力”。 接口就是解决这种问题的重要工具: interface PaymentGateway { public function pay(float $amount): bool; } 之后可以让不同的支付实现遵守同一个接口: class StripeGateway implements PaymentGateway { public function pay(float $amount): bool { // Stripe payment logic return true; } } class PaypalGateway implements PaymentGateway { public function pay(float $amount): bool { // PayPal payment logic return true; } } 调用支付业务的代码只需要依赖 PaymentGateway 这个接口,而不一定需要知道具体使用哪一家支付服务。 这就是多态在实际开发中的价值:同一个抽象接口,可以对应不同的具体实现。 随着 PHP 版本发展,现代 PHP 的类型系统也让类的设计比早期 PHP 更清晰。例如属性和方法可以明确声明类型: class Product { public function __construct( private string $name, private float $price ) {} public function getPrice(): float { return $this->price; } } 这里使用了 PHP 8 引入的构造函数属性提升,把属性声明和构造函数参数结合起来,可以明显减少样板代码。 但语法变得漂亮,并不意味着设计自动变得正确。一个类到底应该保存什么状态、暴露哪些方法、依赖哪些对象,以及哪些业务规则应该放在哪里,依然需要开发者进行判断。 这也是很多初学者学习 OOP 时容易走偏的地方。 看到项目里到处都是 class,并不代表项目设计得好。如果只是把原来的每个函数机械地改成一个类,或者为了“面向对象”给每一个数组都包装一层对象,代码反而可能更加复杂。 一个只有两个字段、只需要简单传递的数据结构,并不一定需要设计成拥有十几个方法的复杂对象。相反,一个涉及状态变化、权限控制、生命周期和业务规则的领域对象,就很适合通过类来建立清晰的边界。 因此,学习 PHP 类和对象时,不应该把目标停留在“会写 class”这一层。 更重要的是理解三个层次。第一层是对象如何保存状态,第二层是对象如何通过方法管理这些状态,第三层则是多个对象之间如何形成清晰的职责关系。 等程序从几十行增长到几千行、几万行以后,真正决定代码是否容易维护的,往往不是用了多少个 class,而是每个类是否知道自己应该负责什么,也是否明确知道哪些事情不应该由自己负责。 面向对象编程不是为了把代码变得更加复杂,而是为了在复杂度已经出现的时候,给它建立边界。好的 OOP 设计不会让程序看起来像一座堆满术语的城堡,而应该让开发者打开代码时,很快就能看懂数据在哪里、规则在哪里、谁负责修改状态,以及不同部分为什么彼此分开。对 PHP 开发者来说,这比背下“继承、封装、多态”几个名词重要得多。

喜欢这篇报道?

使用下面的功能,方便以后继续阅读和分享 MNewsTV

设为 Google 新闻首选来源 让 Google 新闻优先显示 MNewsTV 的最新报道 ›
★ 我的收藏 查看已经收藏的文章
关于文章收藏 收藏不需要注册帐号,收藏信息仅保存在当前浏览器中。 删除收藏请进入「我的收藏」进行管理。
分享这篇报道

捐助(Paypal): https://www.paypal.me/observeccp
订阅中国观察电报 Telegram : https://t.me/s/ObserveCCP