PHP面向对象1.4 封装性

1. 基本的概念

封装性

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

2. 设置私有成员:使用private关键字

封装后的成员在对象的外部不能被访问,但在对象内部的成员方法中可以访问到自己对象内部被封装的成员属性和被封装的成员方法。

2.1 私有成员的访问

可以在对象内部声明一些操作私有属性的公有方法。因为私有成员属性在对象的内部的方法中可以访问。如果成员方法没有加任何访问控制修饰符,默认就是public。
构造方法是一种为私有属性赋值的形式,但是构造方法只能在创建对象时为私有属性赋初值。如果对私有的成员属性通过公有的方法访问,则可以在公有的方法中增加一些限制条件,避免一些非法的操作。

class Person
{
    private $name;
    private $sex;
    private $age;

    function __construct($name = "", $sex = "男", $age = 1)
    {
        $this->name = $name;
        $this->sex = $sex;
        $this->age = $age;
    }


    public function getName()
    {    //获取私有属性值name
        return $this->name;
    }

    public function getSex()
    {  //获取私有属性值sex
        return $this->sex;
    }

    function getage()
    {       //默认也是public,限制访问私有成员属性
        if ($this->age > 30) return $this->age - 10;
        else return $this->age;
    }

    public function setSex($sex)
    {
        if ($sex == "男" || $sex == "女") {   //为私有成员赋值之前进行判断,防止非法操作
            $this->sex = $sex;
        }
    }

    function setAge($age)
    {
        if ($age > 150 || $age < 0)
            return;
        $this->age = $age;
    }
}

$person = new Person("王五", "男", 40);
$person->setSex("女");
$person->setAge(200);
echo $person->getName() . "<br/>";    //结果是"王五"
echo $person->getAge() . "<br/>";     //结果是"30"
echo $person->getsex() . "<br/>";     //结果是"女";

3. __set(),__get(),__isset(),__unset()四个方法

以__两个下划线开头的方法通常被成为魔术方法

__set()

使用private关键字将成员属性封装起来,使对象受到了保护,但是 为了在程序运行过程中可以按要求改变一些私有属性,如按照上面的方法设置一些公有方法操作来操作私有属性,但是如果属性声明较多,则比较麻烦,因此用__set()方法可以解决这个问题。控制对象外部只能为私有的成员属性赋值,防止非法赋值,不能获取私有属性的值。同样要在声明类时加在类中使用。

 void __set(string name,mixed value)//方法体内容需要自定义

不需要任何返回值,但是需要两个参数,第一个需要传入在为私有属性设置值时的属性名。第二个参数则需要传入为属性设置的值。这个方法不需要我们主动调用,可以在方法面前加上private关键字修饰。防止直接调用。

__get()

直接在对象的外部获取私有属性的值时会自动调用此方法。返回私有属性的值。并可以在__get()方法中根据不同的属性,设置一些条件来限制对私有属性的非法取值操作。

mixed __get(string name)  //属性名为参数,返回值为处理后的属性值

这个方法也不需要我们主动调用,可以在方法名前加private防止直接调用

__isset()和__unset()

      如果对象里面的成员属性是共有的,则我们可以直接使用isset()函数来判断这个属性是否存在,但是如果被设为私有的则该函数不起作用,但是如果对象中存在__isset()方法,当在类外使用isset()函数时,就会自动调用类中的__Isset()方法.
      同理unset()方法是用来删除指定的变量的,使用__unset()方法后可以在类外使用unset()方法,就会自动调用类内的__unset()方法,可以删除私有属性成员。

bool __isset(string name) //传入对象中的成员属性名,返回结果
bool __unset(string name)//传入对象中的成员属性名,可以将私有成员属性删除

例如:

class Person
{
    private $name;
    private $sex;
    private $age;

    function __construct($name = "", $sex = "男", $age = 1)
    {
        $this->name = $name;
        $this->sex = $sex;
        $this->age = $age;
    }


    public function __isset($propertyName)
    {
        if ($propertyName == "name")
            return false;
        return isset($this->$propertyName);
    }

    public function __unset($propertyName)
    {
        if ($propertyName == "name")
            return;
        unset($this->$propertyName);
    }

    public function __get($propertyName)
    {
        if ($propertyName == "sex") {
            return "保密";
        } elseif ($propertyName == "age") {
            if ($this->age > 30)
                return $this->age - 10;
            else
                return $this->$propertyName;
        } else {
            return $this->$propertyName;
        }
    }

    public function __set($propertyName, $propertyValue)
    {
        if ($propertyName == "sex") {
            if (!($this->sex == "男" || $this->sex == "女")) {
                //为私有成员赋值之前进行判断,防止非法操作
                return;
            }
        }
        if ($propertyName == "age") {
            if ($this->age > 150 || $this->age < 0)
                return;
        }

        $this->$propertyName = $propertyValue;
    }
}

$person = new Person("王五", "男", 40);
echo $person->name . "<br/>";//结果是"王五"
echo $person->sex . "<br/>";    //结果是"保密"
echo $person->age . "<br/>";     //结果是"30"
var_dump(isset($person->name));//bool(false)不允许测定name属性
var_dump(isset($person->sex));//输出bool(true)存在sex私有属性
var_dump(isset($person->id));//bool(false)不存在id属性
unset($person->name);//删除私有属性name,但是不允许删除
unset($person->age);//删除私有属性age;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值