Blogger Information
Blog 42
fans 3
comment 2
visits 32361
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
PHP第二十九天作业-构造函数\__set和__get魔术方法实例-2018-05-10
HeartofSunny的博客
Original
958 people have browsed it

魔术方法类文件Student.class

<?php

class Student
{
    private $name = '';
    private $cls = '';
    private $age = 0;
    private $data=[];

    //构造方法
    public function __construct($name='',$cls='',$age=0){
        $this->name = $name;
        $this->cls = $cls;
        $this->age = $age;
    }

    //查询器
    public function __get($name)
    {
        $msg = null;
        if(isset($this->$name)){
            $msg = $this->$name;
        }elseif (isset($this->data[$name])) {
            $msg = $this->data[$name];
        } else{
            $msg = '无此属性';
        }
        return $msg;
    }

    //设置器
    public function __set($name,$value)
    {
        if (isset($this->$name)) {
            $this->$name = $value; //输出属性
        }else {
            //如果属性不存在,则创建它并保存到类属性$data数组中
            $this->data[$name] = $value;
        }
    }
}

运行实例 »

点击 "运行实例" 按钮查看在线实例

index.php

<?php

require 'class/Student.php';

//实例化Student类
$student = new Student('张三丰','三年级',12);

//输出学生信息
echo '姓名:',$student->name,'<br>';
echo '班级:',$student->cls,'<br>';
echo '年龄:',$student->age,'<br>';
//echo '爱好:', $student->hobby, '<br>';

echo '<hr>';

$student->name ='张无忌';
$student->cls = '一年级';
$student->age = 10;
echo '姓名:',$student->name,'<br>';
echo '班级:',$student->cls,'<br>';
echo '年龄:',$student->age,'<br>';
//给一个不存在的属性赋值,类中并无hobby字段
$student->hobby = '购物';
echo '爱好:', $student->hobby, '<br>';

//使用类属性设置器__set()再创建一个新属性
$student->sex = '男';
echo '性别:', $student->sex, '<br>';

//直接查看用户自定义的类属性$data数组的内容,此时会输出二个自定义数据
echo '用户自定义属性<pre>'.print_r($student->data,true).'</pre>';

运行实例 »

点击 "运行实例" 按钮查看在线实例

总结:

        在类当中,设计通用的set和get方法,可以简化对属性的读写,这种方法不同于针对于独立的属性的普通的get和set方法,后者针对每个属性,都必须提供一对方法,前者针对所有属性,因此,可以看作是批量定义set和get方法的策略。

        另外一种常见的魔术方法是construct,在这里作为对照进行介绍。

        第一,关于访问权限修饰符。construct设计为public,那么可以在new创建对象时,系统会调用构造方法对对象进行初始化,否则将无法实例化此类(常用于纯静态类,或者单例模式当中),而set和get,设计为private并不影响功能本身,即系统调用这些方法是不受访问权限所左右的。而设计为public,则可以直接调用这些方法本身。

        第二,关于返回值。get方法的返回值,作为属性结果,而construct和set方法的返回值是没有任何意义的,并不会被采用。如下:

        echo $obj->pro = "value";

        打印的值将是value,而不论set方法的返回值是什么。

        第三,关于使用的情境。需要取得$obj->pro值的情况下,会首先寻找公共的pro属性,如果没有找到,会查看是否有get方法,并将其返回值作为结果,如果没有get方法,将会寻找私有属性,找到后会报错,如果私有属性也找不到,会临时创建一个公共属性。

        在$obj->pro = "value"的情况下,会首先寻找公共pro属性,如果没有找到,会启用set方法,如get类似。

        上述语法,在类本身也有用,如果类的某个方法有$obj->pro的表达式,那么,它会首先寻找属性,然后采用get方法,当然,私有属性和公共属性都会被首先寻找,然后才会考虑get方法,set方法类似。

        但是isset魔术方法,是优先于get方法的,也就是说,如果客户端代码如下:

        isset($obj->pro),会首先检查是否有pro公共变量,然后检查isset方法,如果有,将会读取isset方法,然后将返回值确定为检查结果,如果没有,才会考虑用get方法的过程。

        第四,关于继承。这些魔术方法均会被子类继承,继承时,父类可以访问子类中的非私有变量和方法,但是无法访问私有变量和方法。这个问题会导致一个值得注意的细节,比如在父类当中,我们把set方法定义为赋值给一个叫_pro的变量,那么,如果子类直接继承这个set方法,它将能够有效赋值给父类当中定义的私有变量,但是对于子类当中的私有变量,它并没有多态的权限,因此,无法赋值。

Correction status:Uncorrected

Teacher's comments:
Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
0 comments
Author's latest blog post