PHP面向对象三大特性详解:封装、继承与多态实战

青禾
青禾
发布时间:2026-10-15 | 5人浏览过
原创

本文深入解析PHP面向对象的三大核心特性:封装、继承与多态。详细讲解访问控制修饰符的使用、代码复用规则、方法重写机制及多态应用,旨在帮助开发者掌握OOP编程的最佳实践与底层原理。

面向对象的核心概念

面向对象编程(OOP)通过将现实世界中的事物抽象为“类”和“对象”来处理问题。首先简要理解抽象的概念:

在定义一个类时,我们将一类事物共有的属性和行为提取出来,形成一个通用的模板或模型。这种从具体事物中提取共性规律的方法即为抽象。基于此基础,我们进入三大特性的具体学习。

一、封装性(Encapsulation)

封装是将数据(属性)和对数据的操作(方法)捆绑在一起,并将数据隐藏在内层,仅通过授权的方法进行访问。这不仅保护了数据安全,还降低了系统耦合度。

第1步:理解访问控制修饰符

PHP 提供了三种访问控制修饰符,用于限制类成员(属性或方法)的可见范围:

  • public:全局公开。本类内部、类外部以及子类均可访问。若未指定修饰符,默认方法为 public。
  • protected:受保护。仅本类和其子类可以访问,类外部无法直接访问。
  • private:私有。仅本类内部可以访问,子类和外部均无法访问。

注意:成员属性必须显式指定访问修饰符。虽然 PHP4 时代曾使用 var 关键字表示公开属性,但现代开发中已不推荐此种写法。

第2步:实现安全的属性访问

由于私有和保护属性无法在类外部直接读写,通常需要通过公共方法来间接操作。标准做法是提供 getter 和 setter 方法:

// 设置属性值
public function setXxxx($val) {
    $this->xxxx = $val;
}

// 获取属性值
public function getXxxx() {
    // 可以在这里加入验证逻辑,如判断用户名格式等
    return $this->xxxx;
}
代码如下:
<?php
class Person{
    public $name;
    protected $age;
    private $salary;

    function __construct($name,$age,$salary){
        $this->name=$name;
        $this->age=$age;
        $this->salary=$salary;
    }

    public function showinfo(){
        // 本类内部可自由访问所有修饰符的属性
        echo $this->name."||".$this->age."||".$this->salary;
    }
}

$p1=new Person('张三',20,3000);
// 正确做法:通过公共方法访问
// echo $p1->getsalary(); 
// 错误做法:类外部直接访问 protected/private 属性会报错
// echo $p1->age; 
?>

第3步:了解魔术方法的替代方案

除了标准的 getter/setter,PHP 还提供了两个魔术方法来拦截对不存在或未授权属性的操作。虽然功能强大,但官方通常不建议常规业务中使用,仅供了解:

  • __set($name, $val):当尝试给不可见属性赋值时自动触发。
  • __get($name):当尝试读取不可见属性时自动触发。

这两个方法常用于动态代理或调试,但在生产环境中直接使用公共接口能提供更清晰的类型检查和错误提示。

二、继承性(Inheritance)

继承允许创建一个通用类(父类),其他特定类(子类)可以通过继承复用父类的属性和方法,从而减少代码冗余,提高复用性。

第1步:使用 extends 关键字建立继承关系

语法结构为:class 子类名 extends 父类名 {}。子类将自动获得父类中 public 和 protected 的成员,但无法继承 private 成员。

代码如下:
<?php
class Students{
    public $name;
    public $age;
    public function __construct($name,$age){
        $this->name=$name;
        $this->age=$age;
    }
    public function showinfo(){
        echo $this->name.'||'.$this->age;
    }
}

class Pupil extends Students{
    function testing(){
        echo 'Pupil '.$this->name.' is testing';
    }
}

class Graduate extends Students{
    function testing(){
        echo 'Graduate '.$this->name.' is testing';
    }
}

$stu1=new Pupil('张三',20);
$stu1->showinfo();
echo '<br/>';
$stu1->testing();
?>

第2步:掌握继承的细节规则

  1. 单根继承:PHP 不支持多重继承(即一个子类只能有一个直接父类)。如果需要复用多个类的功能,可使用 interface(接口)或 trait,或通过多层继承实现。
  2. 构造函数调用:创建子类对象时,默认不会自动调用父类的构造函数。如果需要在初始化子类时也运行父类逻辑,需在子类构造函数中显式调用 parent::__construct()。
  3. 访问父类成员:在子类中调用父类的方法或属性(尤其是被覆盖或受限的成员),可以使用 parent::方法名() 或 父类名::方法名()。注意关键字需小写。

第3步:学习方法重写(Override)

当子类需要修改父类已有的行为时,可以定义一个与父类方法名、参数完全一致的新方法,这称为方法重写。重写的目的是针对子类特有的情况进行差异化处理。

代码如下:
<?php
class A{
    public function test(){
        echo 'a_test';
    }
}
class B extends A{
    public function test(){
        // 先执行父类逻辑
        parent::test();
        // 再执行子类新逻辑
        echo ' -> b_test';
    }
}
$b=new B();
$b->test(); // 输出: a_test -> b_test
?>

权限约束:子类重写父类方法时,访问权限不能降低。例如,父类是 public,子类必须是 public;父类是 protected,子类可以是 protected 或 public。

三、多态性(Polymorphism)

多态是指同一个行为具有多个不同表现形式或形态的能力。在 PHP 中,它通常表现为:定义了相同的接口或父类方法,不同的子类有不同的实现。当父类引用指向子类对象时,调用该方法会自动执行子类版本。

结合前面的继承案例,我们可以这样理解多态:

代码如下:
<?php
class Animal{
    public $name;
    function cry(){
        echo 'i don\'t know';
    }
}

class Dog extends Animal{
    // 重写父类方法
    function cry(){
        echo 'Wang Wang! '; 
        // 可选:调用父类原始逻辑
        // parent::cry(); 
    }
}

class Cat extends Animal{
    function cry(){
        echo 'Miao Miao!';
    }
}

function makeSound(Animal $animal){
    $animal->cry();
}

$dog1=new Dog();
$cat1=new Cat();

makeSound($dog1); // 输出: Wang Wang!
makeSound($cat1); // 输出: Miao Miao!
?>

补充:模拟方法重载(Overloading)

与其他强类型语言(如 Java/C++)不同,PHP 不支持同名不同参数的函数重载。但我们可以通过魔术方法 __call() 来模拟这一行为。

__call($method, $args):当调用类中不存在或不可见的方法时,会自动触发。其中 $args 是一个包含传递参数的数组。

代码如下:
<?php
class A{
    function test1($p){
        echo 'test1 received: <br/>';
    }
    function test2($p){
        echo 'test2 received: <br/>';
    }
    
    // 魔术方法:模拟重载
    function __call($method,$p){
        if($method == 'test'){ // 假设统一调用名为 test 的方法
            if(count($p)==1){
                $this->test1($p[0]);
            } else if(count($p)==2){
                $this->test2($p[0],$p[1]);
            }
        }
    }
}

$a=new A();
$a->test(5);       // 触发 test1
$a->test(3,5);     // 触发 test2
?>

此外,PHP 还提供了一些有用的魔术常量,如 __LINE__(当前行号)、__FILE__(完整路径)、__DIR__(所在目录)、__FUNCTION__(函数名)、__CLASS__(类名)等,常用于日志记录和调试。

以上就是PHP面向对象三大特性(封装、继承、多态)的详细内容,更多关于PHP高级编程的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表