7.5.3 PHP面向对象封装性之魔术方法1

7.5.3 PHP面向对象封装性之魔术方法1

封装性是面向对象编程中的三大特性之一,封装就是把对象中的成员属性和成员方法加上访问修饰符,使其尽可能隐藏对象的内部细节,以达到对成员的访问控制(切记不是拒绝访问)。
这是PHP5的新特性,但却是OOP语言的一个好的特性。而且大多数OOP语言都已支持此特性。
PHP5支持如下3种访问修饰符:
public (公有的 默认的)
private (私有的)
protected (受保护的)

设置私用成员

只要在声明成员属性或成员方法时,使用private关键字修饰就是实现了对成员的私有封装。封装后的成员在对象的外部不能直接访问,只能在对象的内部方法中使用 $this访问。

<?php
    class Person  {                     
        private $name;             //第一个成员属性$name定义人的名字,此属性被封装
        private $sex;                //第二个成员属性$sex定义人的性别,此属性被封装
        public function __construct($name="", $sex="男") {
            $this->name = $name;        
            $this->sex = $sex;          
         }
        private function leftLeg() {    //声明一个迈左腿的方法,被封装所以只能在内部使用
            return "迈左腿";
        }
     }
<?php
    class Person  {                 
    private $name;            //第一个成员属性$name定义人的名字,此属性被封装
        private $sex;               //第二个成员属性$sex定义人的性别,此属性被封装
            
            public  function setName($name ) {  //通过此方法设置属性name的值
                          $this->name=$name;                 //为对象的私有属性赋值
            }
        public function getName(){            //通过此方法获取属性name的值
                          return $this->name;              //返回当前的私有名字属性
            }        
            public function setSex($sex) {       //通过此方法设置属性sex的值
                          if($sex=="男" || $sex=="女")   //如果传入合法的值才为私有的属性赋值
                                 $this->sex=$sex;             //条件成立则将参数传入的值赋给私有属性
            }
        public function getSex(){               //通过此方法获取属性$sex的值
                          return $this->sex;                 //返回当前的私有性别属性
            }

__set()、__get()、__isset()和__unset()

魔术方法:
__set(): 用于替代通用的set赋值方法
__get(): 用于替代通用的get取值方法
__isset(): 检测对象中成员属性是否存在
__unset(): 销毁对象中成员属性方法
注意:
上面四个魔术方法只对类中的私有、受保护成员属性有效。
魔术方法前的修饰符可以是公有、私有,不影响调用。

__set( )方法:
格式 [修饰符] function __set(string $name,mixed $value){
... }
当我们直接为一个对象中非公有属性赋值时会自动调用此方法,并将属性名以第一个参数(string),值作为第二参数(mixed)传进此方法中。
__get( )方法:
格式:[修饰符] function __get(string $name){ ... }
当我们直接输出一个对象中非公有属性时会自动调用此方法,并将属性名以第一个参数传进去。

<?php
/*
 *   只看封装的一部分, 方法的封装
 *
 *
 *   将一些“特殊的方法 ” 加上一个 关键字 private修饰, 就不能拿到这个对象之后, 用对象中private有的内容, 但对象自己中的其它成员可以使用这个, 因为是自己用自己的成员
 *
 *
 *
 */


    class Person  {
        //成员属性
        private $name;
        private $age;
        private $sex;

        //构造方法
        function __construct($name="", $age=0, $sex="男") {
            $this->name = $name;
            $this->age = $age;
            $this->sex = $sex;
        }   

        function setSex($sex) {
            if(!($sex=="男" or $sex =="女"))
                return;

            $this->sex = $sex;
        }


        function getAge() {
            if($this->age < 20){
                return $this->age;
            }else if($this->age < 30){
                return $this->age - 5;
            }else if($this->age < 40) {
                return $this->age - 8;
            }else{
                return 29;
            }
        }

        //成员方法
        function say() {
            echo "我的名子是:{$this->name}, 我的年龄是:{$this->age},  我的性别是:{$this->sex}.<br>";
        }


        function run() {
            $this->left();      
            $this->left();

            $this->right();
            $this->right();

            $this->go();        
            $this->go();        
            $this->go();        
        }


        private function left() {
            echo "迈左脚<br>";
        }

        private function right() {
            echo "迈右脚<br>";
        }

        private function go() {
            echo "前进<br>";
        }


        function eat() {
            $this->say();
        }

        //析构方法
        function __destruct() {
            echo "再见:{$this->name} <br>";
        }
    
    }

    $p1 = new Person("妹子", 88, "女");

    //$p1->age=120;

//  echo $p1->age;
    //  $p1 -> setSex("男");
    //
    echo $p1 -> getAge();
//  echo $p1->say();

test.php

<?php
/*
 *   只看封装的一部分, 方法的封装
 *
 *
 *   将一些“特殊的方法 ” 加上一个 关键字 private修饰, 就不能拿到这个对象之后, 用对象中private有的内容, 但对象自己中的其它成员可以使用这个, 因为是自己用自己的成员
 *
 *   魔术方法:
 *
 *   __get()
 *
 *      1. 自动调用: 是在直接访问私有成员时,自动调用! 一个参数
 *   __set()
 *      1. 自动调用: 是在直接设置私有属性值时, 两个参数
 *
 *   __isset()   isset()  在使用isset()判断一个私有属性是否存在时, 自动调用__isset()魔术方法, 参数则是属性名称
 *   __unset()  unset();
 *
 */


    class Person  {
        //成员属性
        private $name;
        private $age;
        private $sex;

        //构造方法
        function __construct($name="", $age=0, $sex="男") {
            $this->name = $name;
            $this->age = $age;
            $this->sex = $sex;
        }   



        function __unset($proname) {

            echo "$proname !!!!!!!!!!!!!!!!<br>";

            if($proname != "age")  {
                unset($this->$proname);
            }
        }


        function __isset($proname) {
            if($proname=="age")
                return false;

            return isset($this->$proname);
        }


/*
        function __get($pro) {
            
            return $this->$pro;
        }

        function __set($name, $value) {

            if($name=="age") {
                if($value < 0 or $value > 100)
                    return;
            }
        
            $this->$name = $value;
        }

 */

        //成员方法
        function say() {
            echo "我的名子是:{$this->name}, 我的年龄是:{$this->age},  我的性别是:{$this->sex}.<br>";
        }


        function eat() {
            $this->say();
        }

        //析构方法
        function __destruct() {
            echo "再见:{$this->name} <br>";
        }
    
    }

    $p1 = new Person("妹子", 88, "女");


    unset($p1->name);

    if(isset($p1->name)) {
        echo "这个对象中的name是存的属性<br>";
    }else{
        echo "对象p1中不存在name属性";
    }

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,378评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,356评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,702评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,259评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,263评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,036评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,349评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,979评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,469评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,938评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,059评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,703评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,257评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,262评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,485评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,501评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,792评论 2 345

推荐阅读更多精彩内容