前文说到,封装性是面向对象的三大特征之一。它的核心思想在于把数据域隐藏,使其相对独立并提供相应的方法对其进行操作。它的好处在于能有效防止数据被篡改以及使得类更易于维护。封装性强调以下两点

  • 把对象的属性和方法结合,形成一个不可分割的独立单位
  • 信息隐蔽,即尽可能隐蔽对象的内部细节,对外形成一个边界〔或者说形成一道屏障〕,只保留有限的对外接口使之与外部发生联系

封装的原则在软件上的反映是:要求使对象以外的部分不能随意存取对象的内部数据(属性),从而有效的避免了外部错误对它的”交叉感染”,使软件错误能够局部化,大大减少查错和排错的难度。

举个栗子,假设我们有个模拟账户的类,他有账户名与密码两个被封装的属性,只提供查询功能

<?php

class id {

    //被 private 修饰的变量只能在类的内部被访问
    private $username;
    private $password;

    function __construct($username,$password) {
        $this->username=$username;
        $this->password=$password;
    }

    function getUsername() {
        return $this->username;
    }

    function getPassword() {
        return $this->password;
    }

}

    $id1 = new id("angelment","123");
    echo $id1->getUsername()."<br>".$id1->getPassword();
    /*
      正确的输出方式如上所示
      若采用 echo $id1->username."<br>".$id1->password;
      进行输出将会报错,被 private 关键字修饰的变量无法在类外被访问
    */

?>

同理,方法也可以被 private 修饰,使其变成只能在类的内部使用:

<?php

class id {

    //被 private 修饰的变量只能在类的内部被访问
    private $username;
    private $password;

    function __construct($username,$password) {
        $this->username=$username;
        $this->password=$password;
    }

    function getUsername() {
        return $this->myUsername();
    }

    function getPassword() {
        return $this->myPassword();
    }

    //被 private 修饰的方法也只能在类的内部被访问
    private function myUsername() {
        return $this->username;
    }

    private function myPassword() {
        return $this->password;
    }


}

    $id1 = new id("angelment","123");
    echo $id1->getUsername()."<br>".$id1->getPassword();
    /*
      正确的输出方式如上所示
      若采用 echo $id1->username."<br>".$id1->password;
      或者 echo $id1->myUsername()."<br>".$id1->myPassword();
      进行输出将会报错,被 private 关键字修饰的变量和方法均无法在类外被访问
    */

?>

总结起来,被 private 关键字修饰的属性与方法可视为在他们在类外部是“不可见的”。我们要在类的外部修改这些“不可见的”属性的值或者调用这些“不可见的”方法,就要在类的内部定义一些“可见的”方法,通过这些“可见的”内部的方法来对这些外部“不可见”的内容进行编辑修改或使用

封装的好处是显而易见的,假如我们有如下圆类,我们知道,圆的半径需大于零,若不把半径 $radius 封装起来,就有可能会被错误地赋值

<?php

class circle {

    //使用 private 关键字使其在类的外部“不可见”
    private $radius;

    //为外部提供查询 $radius 的方法
    function getRadius() {
        return $this->radius;
    }

    //为外部提供修改 $radius 的方法
    function setRadius($radius) {
        //调用内部方法
        $this->setter($radius);
    }

    //内部方法,判断半径输入是否正确
    private function setter($radius) {
        if ($radius > 0) {
            $this->radius=$radius;
        }else{
            echo "Error: radius <= 0";
        }
    }

}

?>