面向对象编程(OOP)是现代PHP开发的核心思想,它通过封装、继承、多态等特性,让代码更具可维护性、可扩展性和复用性。本文将从基础概念到实战案例,全面解析PHP面向对象编程的核心知识点。

一、类与对象:OOP的基石

类是对象的"蓝图",定义了对象的属性和方法;对象是类的实例,是具体存在的实体。

// 定义类
class Car {
    // 属性
    public $brand;
    public $color;

    // 构造函数:初始化对象
    public function __construct($brand, $color) {
        $this->brand = $brand;
        $this->color = $color;
    }

    // 方法:对象的行为
    public function displayInfo() {
        return "This is a {$this->color} {$this->brand} car.";
    }
}

// 创建对象(实例化类)
$myCar = new Car("Toyota", "Blue");
echo $myCar->displayInfo(); // 输出:This is a Blue Toyota car.

核心点

  • 类通过class关键字定义,包含属性(数据)和方法(操作);
  • 构造函数__construct()在对象创建时自动调用,用于初始化属性;
  • 通过new关键字创建对象,使用->访问对象的属性和方法。

二、三大特性:封装、继承、多态

1. 封装:隐藏细节,暴露接口

封装将对象的属性和方法捆绑,通过访问修饰符控制访问权限(public/protected/private),仅暴露必要的接口。

class BankAccount {
    // 私有属性:仅类内部可访问
    private $balance;

    public function __construct($initialBalance) {
        $this->balance = $initialBalance;
    }

    // 公共方法:外部通过方法操作属性
    public function deposit($amount) {
        if ($amount > 0) $this->balance += $amount;
    }

    public function getBalance() {
        return $this->balance;
    }
}

$account = new BankAccount(1000);
$account->deposit(500);
echo $account->getBalance(); // 输出:1500

2. 继承:代码复用的利器

继承允许子类复用父类的属性和方法,并可扩展新功能。PHP是单继承语言,一个类只能继承一个父类。

// 父类
class Vehicle {
    public $wheels;
    public function __construct($wheels) {
        $this->wheels = $wheels;
    }
    public function getWheels() {
        return $this->wheels;
    }
}

// 子类:通过extends继承父类
class Bicycle extends Vehicle {
    // 扩展父类功能
    public function ringBell() {
        return "Ring! Ring!";
    }
}

$bike = new Bicycle(2);
echo "Bicycle has {$bike->getWheels()} wheels. {$bike->ringBell()}";

3. 多态:同一接口,不同实现

多态允许不同类对同一方法做出不同响应,通常通过接口或抽象类实现。

// 接口:定义规范
interface Shape {
    public function calculateArea();
}

// 实现接口的类
class Circle implements Shape {
    private $radius;
    public function __construct($radius) {
        $this->radius = $radius;
    }
    public function calculateArea() {
        return M_PI * pow($this->radius, 2);
    }
}

class Rectangle implements Shape {
    private $width;
    private $height;
    public function __construct($width, $height) {
        $this->width = $width;
        $this->height = $height;
    }
    public function calculateArea() {
        return $this->width * $this->height;
    }
}

// 多态:同一方法接收不同实现
function printArea(Shape $shape) {
    echo "Area: " . $shape->calculateArea() . "<br>";
}

printArea(new Circle(5));    // 输出圆形面积
printArea(new Rectangle(4,6)); // 输出矩形面积

三、魔术方法:PHP的"暗箱操作"

魔术方法是具有特殊名称的方法,在特定场景下自动调用,增强类的灵活性。

方法 触发场景
__construct() 对象创建时(构造函数)
__destruct() 对象销毁时(析构函数)
__toString() 对象被当作字符串使用时
__get()/__set() 访问/设置不可访问的属性时
__call() 调用不存在的方法时

示例:__toString()的使用

class Book {
    private $title;
    private $author;
    public function __construct($title, $author) {
        $this->title = $title;
        $this->author = $author;
    }
    // 当对象被echo时自动调用
    public function __toString() {
        return "Book: {$this->title} by {$this->author}";
    }
}

$book = new Book("The Great Gatsby", "F. Scott Fitzgerald");
echo $book; // 输出:Book: The Great Gatsby by F. Scott Fitzgerald

四、方法重载与访问修饰符

子类可重载(重写)父类的方法,但需遵循访问修饰符规则:子类方法的访问权限不能比父类更严格

class ParentClass {
    protected function protectedMethod() {
        echo "Parent method";
    }
}

class ChildClass extends ParentClass {
    // 正确:子类方法权限更宽松(protected → public)
    public function protectedMethod() {
        echo "Child method";
    }
}

规则

  • 父类public → 子类只能public
  • 父类protected → 子类可protectedpublic
  • 父类private → 子类无法重载(可定义同名方法,但不算重载)。

五、设计模式:单例模式

单例模式确保一个类只有一个实例,并提供全局访问点,适用于数据库连接、日志器等场景。

class DatabaseConnection {
    // 存储唯一实例
    private static $instance;

    // 私有构造函数:禁止外部实例化
    private function __construct() {
        echo "Database connected";
    }

    // 禁止克隆
    private function __clone() {}

    // 禁止反序列化
    private function __wakeup() {}

    // 公共静态方法:获取实例
    public static function getInstance() {
        if (!self::$instance) {
            self::$instance = new self();
        }
        return self::$instance;
    }
}

$db1 = DatabaseConnection::getInstance();
$db2 = DatabaseConnection::getInstance();
var_dump($db1 === $db2); // 输出:bool(true)(同一实例)

六、代码复用进阶:Trait

Trait是PHP解决单继承限制的机制,允许在多个类中复用方法,优先级:当前类方法 > Trait方法 > 父类方法

// 定义Trait
trait Loggable {
    public function log($message) {
        echo "Log: {$message}";
    }
}

// 使用Trait
class User {
    use Loggable; // 引入Trait
    public function register() {
        $this->log("User registered"); // 调用Trait方法
    }
}

$user = new User();
$user->register(); // 输出:Log: User registered

解决冲突:当多个Trait有同名方法时,用insteadofas处理:

trait A { public function hello() { echo "A"; } }
trait B { public function hello() { echo "B"; } }

class C {
    use A, B {
        A::hello insteadof B; // 使用A的hello
        B::hello as helloB; // 将B的hello重命名为helloB
    }
}

$c = new C();
$c->hello(); // 输出:A
$c->helloB(); // 输出:B

七、其他实用特性

1. 匿名类

PHP 7引入的匿名类,适合创建临时、简单的类实例:

// 匿名类实现接口
interface Logger {
    public function log($message);
}

$logger = new class implements Logger {
    public function log($message) {
        echo "Logging: {$message}";
    }
};

$logger->log("Test"); // 输出:Logging: Test

2. 命名空间

解决类名冲突,类似文件系统的目录结构:

// 文件:src/Utils/StringHelper.php
namespace MyProject\Utils;

class StringHelper {
    public static function reverse($str) {
        return strrev($str);
    }
}

// 使用时导入
use MyProject\Utils\StringHelper as SH;
echo SH::reverse("Hello"); // 输出:olleH

八、实战案例:面向对象版图形计算器

// 抽象类:定义图形通用接口
abstract class Shape {
    abstract public function calculateArea();
    abstract public function calculatePerimeter();
}

// 圆形
class Circle extends Shape {
    private $radius;
    public function __construct($radius) {
        $this->radius = $radius;
    }
    public function calculateArea() {
        return M_PI * pow($this->radius, 2);
    }
    public function calculatePerimeter() {
        return 2 * M_PI * $this->radius;
    }
}

// 矩形
class Rectangle extends Shape {
    private $width;
    private $height;
    public function __construct($width, $height) {
        $this->width = $width;
        $this->height = $height;
    }
    public function calculateArea() {
        return $this->width * $this->height;
    }
    public function calculatePerimeter() {
        return 2 * ($this->width + $this->height);
    }
}

// 测试
$circle = new Circle(5);
echo "Circle Area: " . $circle->calculateArea(); // 约78.54

总结

PHP面向对象编程通过类与对象、三大特性、魔术方法、Trait等机制,为复杂项目提供了清晰的代码组织方式。掌握这些知识点,能有效提升代码的复用性和可维护性,是进阶PHP开发的必备技能。在实际开发中,应根据场景灵活运用设计模式,结合命名空间和自动加载,构建高效、规范的PHP应用。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐