php继承--属性,方法重载

思考:php对象复合数据类型,如果直接echo 输出对象会报错的,这样的报错会给用户体验不好,有没有办法能够解决这类问题呢?

引入:虽然上述问题出现是因为程序员的误操作,但是的确有可能出现这样的问题,尤其是我们的程序是给外部调用时,所以,面向对象关于很多对象可能出现

了一种容错机制,这种机制叫做重载。

php重载【了解】

定义 重载overload,本意指一个类中可以出现多个同名方法,彼此之间的参数个数和类型不一样,但是php中不支持同名方法,而且也不区分数据类型(所类型语言)

所以php不支持传统重载,php中的重载指的是当某些不允许操作发生时,会自动调用的一种内部机制,即自动调用相关的魔术方法。

1.魔术方法:指系统为类中预先设计好的,只需要开发者实际的方法,魔术方法以双下划线__开头,对象在某些特定情况下会自动调用的方法,构造方法,析构方法和克隆方法就是魔术方法

<?php


class posoen{
    public $name;
}

$s=new man();      //实例化后对象自动调用  触发时机:对象实例化

2.php重载是指某些容错处理(也可以理解:为了某些特殊情况下而自动调用),在访问没有权限或者不存在的属性或者方法的时候,会自动触发的魔术方法

  方法重载

  属性重载

3.属性重载:当php对象访问不存在的或这没有权限访问的属性时候会自动调用的方法

  __get($key):读属性的时候触发

  __set($key):写属性的时候触发

  __inset($key):外部调用isset()函数或者empty()函数时自动触发

  __unset($key):外部调用isset()结构删除对象属性时自动触发

  __tostring():对象被当作普通变量输出或者连接时自动调用

<?php


class posen{
    private $name='duwei';


    //重载方法
    //读取重载
    function __get($key){
        echo $key.__METHOD__.'<br>';
    }

    //写重载
    function __set($key,$values){
        echo $key.':'.$values.__METHOD__.'<br>';
    }

    //判定重载
    function __isset($key){
        echo $key.__METHOD__.'判定了我'."<br>";
    }

    //删除重载
    function __unset($key){
        echo $key.__METHOD__.'你想删除我'.'<br>';
    }

    //普通输出
    function __tostring(){
        echo '-----'.__METHOD__.'还是我'.'<br>';
        return '不可能';
    }
}

$s=new posen();      //实例化后对象自动调用  触发时机:对象实例化
//访问
echo $s->name;      //类中私有属性,外部访问 提示name posen__get()
//设置
$s->name="tianguo";     //给私有属性赋值,本来就会报错  所以触发了__set()
//判定
isset($s->name);        //判定私有属性也会报错  出发了__isset();..........
//删除
unset($s->name);
//输出
echo $s;                //输出对象,报错  触发__tostring()

4.属性重载的目的:一方面为了不让程序运行出错,另一方面可以在类内部由我们自己控制内容的访问。

<?php


class posen{
    private $name='duwei';   //私有不允许外部访问
    private $age='80';

    //重载方法
    //读取重载
    function __get($key){

        //定义一个允许访问列表:假设有很多私有属性
        $list=array('age');
        //判断是否在列表内,在就允许访问,不在就返回null或者false
        if(in_array($key,$list)){
            return $this->$key;        //可变属性;$key是外部访问的目标,最终为$this->age;
        }else{
            return '抱歉,这个属性不能访问';
        }
                
    }

    //写重载
    function __set($key,$value){
        if($value<50){
            $this->$key=$value;
        }else{
            echo '这个数值我不能接受';
        }
    }


}

$s=new posen();     
echo $s->name;        //输出抱歉,这个属性不能访问
$s->age=33;           //设置成功
$s->age=100;          //设置失败 这个值我不能接受
echo $s->age;      //输出33

注意:属性的重载,就相当于c#中的属性get和set,非常相似。

可变参数,就相当于__construct()函数一样,当你实例化一个类的时候,调用的是构造函数__construct(),如果构造函数中有参数,必须在

实例化的时候也要添加上参一样,比如我们读取的操作,就是调用了__get($key)函数,其中$key 就是我们在外部调用对象输出的属性($s->name)name就是$key

  读:指定访问列表,在就允许,不在就null或false

  写:与get理论相似:允许就设置,不允许就说明都不操作

  判定:给出内部判定结果

  输出普通:返回一个指定的字符串(一般当类有属性保存某些信息时,输出某个属性)

5.方法重载:当php对象访问不存在的方法或者不允许访问的方法时自动调用的方法,(抑或时谋者特殊情况,如构造方法)

  __call($function_fname,$args):对象调用不可调用方法时触发

  __callsttatic($function_name,$args):类访问不可调用静态方法时触发

class man{
    private static function show(){
        echo "看看你能访问我吗?";
    }

    //普通方法重载,参数必须有方法的名字和参数
    public function __call($fun,$args){
        echo __METHOD__;
    }

    //静态方法重载,参数必须有方法的名字和参数
    public static function __callstatic($fun,$args){
        echo __METHOD__;
    }

}

$s=new man();
$s->add();          //调用对象中没有的方法  触发了__call重载
man::show();        //调用类中不允许访问的静态方法  触发了__callstatic重载

6.方法重载的主要目的:不让外部访问出错,当然如果必要时也可以进行内部访问

class man{
    private static function show(){
        echo "看看你能访问我吗?";
    }

    //普通方法重载,参数必须有方法的名字和参数
    public function __call($fun,$args){
        //定义允许访问的方法列表
        $list=array('show');
        //判断是否存在列表中
        if(in_array($fun,$list)){
            return $this->$fun($args);
        }else{
            return false;
        }
    }

    //静态方法重载,参数必须有方法的名字和参数
    public static function __callstatic($fun,$args){
        echo __METHOD__;
    }

}

$s=new man();
$s->show();        //成功访问  看看你能访问我吗?

总结:

  1.hp重载不是指同名方法,而是指对象或这类在访问一些不允许或者不存在的属性或者方法的时候自动调用的魔术方法

  2.php重载分为属性和方法重载

  3.php重载的目的是为了保护程序正确的运行,而提供的一种容错机制

  4.并非所有类都需要实现这些重载,只是如果有类需要对外提供访问使用时才有必要采取