类是PHP中定义对象的模板,包含属性和方法;对象是类的实例。使用class定义类,通过new创建对象。构造函数__construct用于初始化对象,析构函数__destruct在对象销毁时调用。可见性修饰符public、protected、private控制成员访问权限,实现封装。继承通过extends实现,子类可扩展父类功能,需显式调用parent::__construct()以执行父类构造函数。OOP的核心价值在于封装、继承和多态,提升代码复用性、可维护性和扩展性,适用于复杂项目开发。

在PHP中,定义一个类就像是绘制一张蓝图,它描述了一类事物的共同特征(属性)和行为(方法)。而对象,则是这张蓝图的具体实现,是类的实例化。简单来说,类是抽象的模板,对象是具体的实体。
要定义一个PHP类,我们使用
class
{}<?php
// 定义一个名为 'Car' 的类
class Car {
// 属性(特性),描述车的状态
public $brand; // 品牌
public $model; // 型号
public $color; // 颜色
private $engineStatus = "off"; // 引擎状态,私有属性,只能在类内部访问
// 构造函数:当创建一个新对象时自动调用,用于初始化属性
public function __construct($brand, $model, $color) {
$this->brand = $brand;
$this->model = $model;
$this->color = $color;
echo "一辆新的 {$this->color} {$this->brand} {$this->model} 被制造出来了!\n";
}
// 方法(行为),描述车能做什么
public function startEngine() {
if ($this->engineStatus === "off") {
$this->engineStatus = "on";
echo "{$this->brand} {$this->model} 的引擎启动了。\n";
} else {
echo "{$this->brand} {$this->model} 的引擎已经启动了。\n";
}
}
public function stopEngine() {
if ($this->engineStatus === "on") {
$this->engineStatus = "off";
echo "{$this->brand} {$this->model} 的引擎关闭了。\n";
} else {
echo "{$this->brand} {$this->model} 的引擎已经关闭了。\n";
}
}
public function getEngineStatus() {
return $this->engineStatus;
}
// 析构函数:当对象不再被引用或脚本结束时自动调用
public function __destruct() {
echo "{$this->brand} {$this->model} 的生命周期结束了。\n";
}
}
// 创建(实例化)对象:使用 'new' 关键字
$myCar = new Car("Toyota", "Camry", "Blue"); // 调用构造函数
// 访问对象的属性
echo "我的车是:{$myCar->color} 的 {$myCar->brand} {$myCar->model}\n";
// 调用对象的方法
$myCar->startEngine();
echo "引擎状态: " . $myCar->getEngineStatus() . "\n";
$myCar->stopEngine();
echo "引擎状态: " . $myCar->getEngineStatus() . "\n";
echo "\n";
$anotherCar = new Car("Honda", "Civic", "Red");
$anotherCar->startEngine();
$anotherCar->startEngine(); // 尝试再次启动
$anotherCar->stopEngine();
// 当脚本执行完毕,或者对象被显式销毁(如 unset($myCar)),析构函数会被调用。
// 这里,它们会在脚本结束时自动调用。
?>在这个例子里,
Car
$myCar
$anotherCar
Car
new Car(...)
在我刚接触编程的时候,写代码总是习惯性地从头到尾一条龙式地写下来,遇到重复逻辑就复制粘贴或者封装成函数。这对于小脚本来说确实没问题,但一旦项目规模稍微大一点,比如要管理几十种不同类型的用户、订单、商品,那代码就会变得异常混乱,改一个地方可能牵一发而动全身,维护起来简直是噩梦。这就是面向对象编程(OOP)真正展现其价值的地方。
立即学习“PHP免费学习笔记(深入)”;
对我来说,OOP的核心魅力在于它提供了一种更贴近现实世界思维的组织代码的方式。我们不再把数据和处理数据的逻辑分开来考虑,而是将它们紧密地“捆绑”在一起,形成一个独立的、有行为能力的“对象”。这种“捆绑”带来的直接好处就是封装性(Encapsulation)。它意味着一个对象内部的实现细节可以被隐藏起来,外部只需要知道如何与它交互(通过公共方法),而不需要关心它是如何工作的。这极大地降低了系统的复杂度,提高了代码的模块化程度。
再者,OOP通过继承(Inheritance)机制,让我们可以基于现有类创建新类,共享和扩展功能。想象一下,你定义了一个通用的
Vehicle
Car
Motorcycle
Truck
Vehicle
最后,多态性(Polymorphism)则允许我们用统一的接口处理不同类型的对象。比如,所有的
Vehicle
drive()
Car
drive()
Motorcycle
drive()
在PHP中,当我们定义类的属性和方法时,前面通常会加上
public
protected
private
public
public
public
Car
startEngine()
protected
protected
protected
private
private
private
private
Car
$engineStatus
private
startEngine()
stopEngine()
$engineStatus
选择合适的可见性修饰符是一个设计上的考量。一开始学习时,很多人可能会习惯性地把所有东西都设为
public
__construct()
__construct()
new
在上面的
Car
$myCar = new Car("Toyota", "Camry", "Blue");__construct("Toyota", "Camry", "Blue")$this->brand
$this->model
$this->color
Car
常见误区和需要注意的地方:
忘记在子类中调用父类的构造函数:这是一个非常常见的错误。当你有一个子类继承了父类,并且子类也有自己的构造函数时,PHP默认不会自动调用父类的构造函数。这意味着父类中定义的任何初始化逻辑都不会执行。
class SportsCar extends Car {
public $turbo;
public function __construct($brand, $model, $color, $turbo) {
// 错误示范:忘记调用父类的构造函数
// $this->brand = $brand; // 需要手动赋值,或者...
// $this->model = $model;
// $this->color = $color;
$this->turbo = $turbo;
echo "一辆运动型汽车 {$this->color} {$this->brand} {$this->model} 被制造出来了!\n";
}
}
// 正确的做法是在子类构造函数中显式调用 `parent::__construct()`:
class CorrectSportsCar extends Car {
public $turbo;
public function __construct($brand, $model, $color, $turbo) {
parent::__construct($brand, $model, $color); // 关键一步!
$this->turbo = $turbo;
echo "一辆带涡轮的运动型汽车 {$this->color} {$this->brand} {$this->model} 被制造出来了!\n";
}
}
// $mySportsCar = new SportsCar("Ferrari", "488", "Red", true); // brand, model, color可能未被初始化
$myCorrectSportsCar = new CorrectSportsCar("Porsche", "911", "Yellow", true);
echo "我的运动车是:{$myCorrectSportsCar->color} 的 {$myCorrectSportsCar->brand} {$myCorrectSportsCar->model}\n";如果不调用
parent::__construct()
SportsCar
Car
$brand
$model
$color
构造函数不返回值:
__construct()
return
过度复杂化构造函数:有时候,为了初始化对象,我们可能会在构造函数中执行很多复杂的操作,比如数据库连接、文件读写等。虽然这在某些情况下是合理的,但如果构造函数变得过于庞大和复杂,可能会导致对象创建过程变得缓慢,并且难以测试。更好的做法是让构造函数保持简洁,只负责必要的属性赋值,将其他复杂逻辑委托给其他方法或服务。
在我看来,
__construct()
PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号