zoukankan      html  css  js  c++  java
  • 初识访问控制修饰符及魔术方法

    访问控制修饰符:

      访问控制修饰符: 访问控制修饰符可以修饰成员属性,也可以修饰方法,有 public(公有),protected(受保护)和 private(私有)三种。

       代码说明:

    class Clerk{
        public $name;
        protected $salary;
        private $lover;
        //构造函数
        public function __construct($name,$salary,$lover){
            $this -> name = $name;
            $this -> salary = $salary;
            $this -> lover = $lover;
        }
        public function getSalary(){
            return $this -> salary;
        }
        public function getLover(){
            return $this -> lover;
        }
    }
    $clerk = new Clerk('小明',15000,'翠花');
    //访问各个属性
    //如果访问修饰符是public则可以直接访问
    echo '<br>职员的名字是' . $clerk -> name;
    //如果访问修饰符是protected,则不能直接访问,需要通过编写一个public成员方法来操作protected属性
    echo "<br>" . $clerk -> name . '的薪水是' . $clerk -> getSalary();
    //如果访问修饰符是private,则不能直接访问,需要通过编写一个public成员方法来操作private属性
    echo "<br>" . $clerk -> name . '的爱人是' . $clerk -> getLover();
    页面输出:
        职员的名字是小明
        小明的薪水是15000
        小明的爱人是翠花

    property_exists()函数:

      1. 先判断该对象是否有这个属性,如果有则返回真.

      2. 如果该对象没有有这个属性, 则继续判断该对象对应的类是否定义过这个属性,如果定义过仍然返回真,否则才返回假

    魔术方法:

        __get 和 __set函数:

        基本介绍:

          (1)当程序员去使用不可以访问的属性时,系统就会调用__get方法.

          (2)不可以访问的属性指的是(1 . 该属性不存在 2. 直接访问了protected或者private属性)

          (3)当程序员去给不可以访问的属性直接赋值,系统就会调用__set方法

      快速入门案例:

    class Monkey{
        public $name;
        protected $food;
        public function __construct($name,$food){
            $this -> name = $name;
            $this -> food = $food;
        }
        //魔术方法__get
        //1.魔术方法的名字是固定的,系统提供
        //2.$pro_name是形式参数,表示属性名
        public function __get($pro_name){
            //property_exists检查对象或类是否具有该属性
            return property_exists($this,$pro_name) ? $this -> $pro_name : '没有该属性无法返回' ;
        }
        //魔术方法__set
        //1.魔术方法的名字是固定的,系统提供
        //2.$pro_name表示属性名,$pro_val表示要传入的属性值
        public function __set($pro_name,$pro_val){
            //property_exists检查对象或类是否具有该属性
            return property_exists($this,$pro_name) ? $this -> $pro_name = $pro_val: '属性值不存在无法赋值' ;
        }
    }
    $monkey = new Monkey('孙悟空','香蕉');
    echo '<br>猴子的名字是' . $monkey -> name;
    //直接访问访问修饰符protected,会把成员属性名作为传参传入__get函数中
    echo '<br>猴子喜欢吃' . $monkey -> food;
    var_dump($monkey);
    //修改猴子的名字和食物
    $monkey -> name = '战斗佛';
    // 在默认情况下不能直接给修饰符protected的属性赋值,会触发__set魔术方法
    $monkey -> food = '元宝蜡烛';
    echo '<br>猴子的名字是' . $monkey -> name;
    echo '<br>猴子喜欢吃' . $monkey -> food;
    var_dump($monkey);

      __isset 和 __unset函数:

           基本介绍:

          (1)   当对不可访问的属性进行了 isset($对象名->属性), empty($对象名->属性)操作,那么__isset函数就会被系统调用。

          (2)   不可访问的属性 仍然和前面说的一样 。

          (3)   当对不可访问的属性进行了 unset($对象名->属性), 那么__unset函数就会被系统调用

        快速入门案例:

    class Monkey{
        public $name;
        protected $food;
        public function __construct($name,$food){
            $this -> name = $name;
            $this -> food = $food;
        }
        public function __isset($pro_name){
            return property_exists($this,$pro_name) ? true : false;
        }
        public function __unset($pro_name){
            if(property_exists($this,$pro_name)){
                unset($this -> $pro_name);
            }else{
                echo '<br>$pro_name属性不存在无法unset';
            }
        }
    }
    $monkey = new Monkey('孙悟空','香蕉');
    //当访问修饰符为public时可以直接用isset()进行判断
    echo isset($monkey -> name) ? 'name属性是存在的' : 'name属性不存在';
    echo '<br>';
    //当访问修饰符为protected、private时会触发__isset(),会把成员属性名传入__isset()函数中
    echo isset($monkey -> food) ? 'food属性是存在的' : 'food属性不存在';
    //当访问修饰符为public时可以直接用unset()将成员属性直接销毁
    unset($monkey -> name);
    //当访问修饰符为protected、private时,会把成员属性名传入__unset()函数中
    unset($monkey -> food);
    //打印($monkey结果为空对象
    var_dump($monkey);

      __toString函数:

       1.该函数没有形参
       2.该函数要求返回值时一个字符串
          3.当我们在项目开发时需要抓取bug(debug)可以通过该函数输出对象信息

      快速入门案例:

    class Monkey{
        public $name;
        protected $food;
        public function __construct($name,$food){
            $this -> name = $name;
            $this -> food = $food;
        }
        //魔术方法__toString:当输出一个对象时就会触发这个函数
        public function __toString(){
            return '名字:' . $this -> name . '喜欢的食物:' . $this -> food;
        }
    }
    $monkey = new Monkey('孙悟空','香蕉');
    //当输出一个对象时就会触发__toString函数
    echo $monkey;
    输出结果为:
    名字:孙悟空喜欢的食物:香蕉

       __clone函数:

        说明:

        (1)   当我们 $对象1 = clone $对象2, 会触发 __clone 方法

        (2)   如果我们希望在克隆时,修改某个属性,则在__clone方法中去修改即可

        (3)   如果我们希望阻止克隆,只需要将 __clone 魔术方法申明为private 即可.

        快速入门案例:

    class Monkey{
        public $name;
        public $age;
        protected $food;
        public function __construct($name,$age,$food){
            $this -> name = $name;
            $this -> age = $age;
            $this -> food = $food;
        }
        //可以对克隆对象中的某一个属性值进行更改
        public function __clone(){
            $this -> food = '苹果';
        }
    }
    $monkey = new Monkey('孙悟空',5,'香蕉');
    //$monkey1 = new Monkey('孙悟空',5,'香蕉')等价于$monkey1 = clone $monkey;
    //对象的克隆会触发__clone函数
    $monkey1 = clone $monkey;
    var_dump($monkey,$monkey1);

      __call函数:

          基本介绍:

          (1)     当我们调了一个不可以访问的成员方法时,__call魔术方法就会被调用.

          (2)     不可以访问的成员方法的是指(1. 该成员方法不存在, 2. 成员方法是protected或者 private)

    class Cat{
        public $name;
        public $age;
        public function __construct($name,$age){
            $this -> name = $name;
            $this -> age = $age;
        }
        protected function jisuan($num1,$num2,$oper){
            $res = 0;
            switch ($oper) {
                case '+':
                    $res = $num1 + $num2;
                    break;
                case '-':
                    $res = $num1 - $num2;
                    break;
                case '*':
                    $res = $num1 * $num2;
                    break;
                case '/':
                    $res = $num1 / $num2;
                    break;
                default:
                    echo '你的运算符号有误';
            }
            return $res;
        }
        public function __call($method_name,$parameters){
            if($method_name == 'play'){
                if(method_exists($this, $parameters[0])){
                    return call_user_func_array([$this, $parameters[0]],array_slice($parameters, 1));
                }else{
                    return '你调用的' . $parameters[0] . '不存在';
                }
            }else{
                return '你调用的方式有问题';
            }
        }
    }
    $cat = new Cat('加菲猫',15);
    echo '<br>运算的结果是' . $cat -> play('jisuan',10,20,'+');
  • 相关阅读:
    C++之路进阶——codevs2439(降雨量)
    C++之路进阶——codevs2933(诗人小G)
    C++之路进阶——bzoj2879(美食节)
    C++之路进阶——bzoj1934(善意的投票)
    C++之路进阶——bzoj3876(支线剧情)
    C++之路进阶——codevs1281(Xn数列)
    八数码难题
    道路游戏
    细胞分裂
    最长链
  • 原文地址:https://www.cnblogs.com/rickyctbur/p/11044550.html
Copyright © 2011-2022 走看看