继承,静态绑定,重载与Trait技术总结

Original 2018-11-26 11:00:04 189
abstract:一.类的继承    + 类的继承,是为了代码复用    + PHP只支持单继承    + 继承必须发生在二个或二个以上的类之间    + 父类也叫超类,基类,子类也叫派生类    之前我们是用函数来实

一.类的继承

    + 类的继承,是为了代码复用
    + PHP只支持单继承
    + 继承必须发生在二个或二个以上的类之间
    + 父类也叫超类,基类,子类也叫派生类

    之前我们是用函数来实现代码复用,现在我们用类的继承来实现代码复用
    类继承使用 extends关键字

    *  继承环境下:
    * protected,public 可以在子类中访问
    * 访问限制符是受到类作用域限制
    * 类常量,不受限制的.可以在子类中直接使用

class ParentClass
{

    public $name;
    protected $course;
    private $salary;
    const SITE_NAME = 'PHP中文网';

    //构造方法
    public function __construct($name,$course,$salary)
    {
        $this->name = $name;
        $this->course = $course;
        $this->salary = $salary;
    }
    //访问本类私有成员
    public function getSalary()
    {
        return $this->salary;
    }
    public function getCourse()
    {
        //受保护的成员,可以在子类中访问
        return $this->course;
    }
}
//创建子类,继承自parentClass 类
class ChildClass extends ParentClass
{
    //子类中允许重写父类中的同名方法,也叫多态
    public function getCourse()
    {
        //受保护的成员,可以在子类中访问
//        return $this->course;
        return $this->name.'的成名地点是'.parent::getCourse();
    }

    public function getSalary()
    {
//        return $this->salary;
    }
}
$child = new ChildClass('张辽','白门楼',8000);
echo $child->name.'<br>';
//echo $child->course.'<br>';//访问失败  父类受保护的属性
echo $child->getCourse().'<br>';

//echo $child->getSalary();   //失败  不可以访问父类中私有属性
echo ChildClass::SITE_NAME.'<br>';

二.范围解析符的使用

    * 使用场景:
      + 访问类中的静态成员
      + 访问类中的常量

    * 使用主体:
      + 在类中使用关键字:self static parent
      + 在类外可直接使用类名:className

class Book
{
    //声明一个普通的动态成员属性
    public $name = "mysql从删库到跑路";

    //声明静态成员的属性
    protected static $author = '朱老师';

    //类常量,不要设置访问限制,本身就属于类的
    const PRICE = 99;

    //动态方法,既可以访问动态成员,也可以访问静态成员
    public function getInfo1()
    {
        //普通动态成员
//        return $this->name;
        //静态成员
        //尽管可以在普通方法中访问静态成员,但是推荐尽可能不用这样做
//        return self::$author;   //self::$成员名
        return self::PRICE;

    }
    //静态方法,属于类的必须要用类来调用,可以被所有该类的对象所共享
    public static function getInfo2()
    {
        //普通动态成员,不能访问
//        return $this->name;
        //静态成员
//        return self::$author;   //self::$成员名
        return self::PRICE;
    }

}

//子类Study 继承自Book类
class Study extends Book
{

    public static function getInfo3()
    {
        //访问父类的静态成员
//        return Book::$author;
        //应该使用当前父类的引用标识:parent
//        return parent::$author;
        return static::$author;
    }

}
$book = new Book();
//echo $book->name;
echo $book->getInfo1();
//echo Book::getInfo2();

$study = new Study();
echo $study->getInfo3();

三.static关键字

    用处如下:

    + 定义与访问类中的静态成员;
    + 访问类常量
    + 后期静态绑定(延迟静态绑定)

class MyClass
{

    //const 定义类常量
    const DOMAIN = 'm.sbmmt.com';

    //static 定义静态属性:被类的所有实例所共享

    public static $desc = '免费公益,海量资源';

    //静态方法
    public static function getDesc()
    {
        //类常量
//        $domain = self::DOMAIN;
        $domain = static::DOMAIN;

        //静态属性
//        $desc = self::$desc;
        $desc = static::$desc;

        return '('.$domain.')'.$desc;
    }

}

//外部访问类中的静态属性
echo MyClass::$desc.'<br>';
echo MyClass::getDesc();

四.后期静态绑定 (static)

    + 使用在静态继承的上下文环境中;
    + 动态匹配静态成员的调用者,而不是声明者;(谁调用我,我就是谁)
    + 静态方法调用者绑定运行阶段才可以确定

//定义一个父类
class Father
{

    //静态属性
    public static $money = 50000;

    //静态方法
    public static function getClass()
    {
        //返回当前类名
        return __CLASS__;
    }
    //静态方法
    public static function getMoney()
    {
//        return self::getClass().'=>'.self::$money;        //如果这样定义子类继承之后调用返回的是父类的self
        //static用在静态继承的上下文中,调用者是动态的,动态设置静态成员的调用者(调用主体)
        return static::getClass().'=>'.static::$money;
    }
}

//定义子类,继承自Father

class Son extends Father
{
    //覆写父类的静态属性
    public static $money = 30000;

    //覆写父类的静态方法
    public static function getClass()
    {
        //返回当前类名
        return __CLASS__;
    }

}

//调用Father中的静态方法,来获取一下类名
echo Father::getClass().'<br>';
echo Father::getMoney().'<br>';

//调用子类Son类中的静态成员
echo Son::$money.'<br>';
echo Son::getClass().'<br>';
echo '<hr>';

//子类中调用父类中的getMoney()
echo Son::getMoney(),'<br>';    //希望返回Son::30000  而现在返回的是父类的值    改成static就变成希望的返回值了

五.重载技术

    + 重载: 动态创建类属性和方法;
    + 属性重载:
        * __set($name,$value)
        * __get($name)
        * __isset($name)
        * __unset($name)
    + 方法重载:    (当用户调用一个不存在的普通方法时触发__call 当用户调用一个没有访问权限或着不存在的静态方法自动调用__callstatic)  
        * __call($method,array $args)
        * __callStatic($method,array $args)

    重载的实现手段:通过魔术方法

        1.属性重载

        __set(), __get()  __isset() , __unset() 当设置,调用,判断是否存在,销毁 类中不存在的属性,或者不可访问的属性时 ,会调用属性重载

class Visit
{
    protected $data = [];            //声明一个空数组
    public function __isset($name)    //$name属性不存在或者受保护的时候调用
    {
        return isset($this->data[$name]);        //因为这个$name属性不存在    返回false
    }
    public function __get($name)    //当调用的$name 属性不存在或者受保护的时候, 设置$data的一个值
    {
        return $this->data[$name];
    }

    public function __set($name,$value)    //当设置$name 的值 不存在或者受保护的时候, 设置$data的一个元素为这个不存在的值
    {
        $this->data[$name] = $value;
    }
    public function __unset($name)        //当销毁一个不存在的值或者受保护的属性  提示不让他销毁
    {
            echo '禁止销毁';
    }

}
$visit = new Visit();

if(isset($visit->table)){   //判断是否存在
    echo $visit->table,'<br>';    //存在就输出它
}else{
    $visit->table = 'table_staff';  //更新操作 不存在就设置他    
}

//因为上边他不存在,所以走的else __set我设置方法让他给$data['table']设置了值'table_staff' 当我调用不存在的table属性, __get 我设置的让他返回$data['table']的值 ,所以返回成功了
echo $visit->table,'<br>';        //table_staff

unset($visit->table);    //禁止销毁

        2,方法重载 __call(),__callStatic()

        当访问一个不存在的一个动态普通方法的时候会自动调用__call()

        当访问一个不存在的一个静态方法的时候会自动调用__callStatic()

        方法重载更多用在跨类的方法调用

require 'public/Site.php';
class Web
{
    //当访问一个不存在的一个动态普通方法的时候会自动调用
    public function __call($name, $arguments)
    {
//        return '方法是:'.$name.'<br>'.'参数列表:'.var_export($arguments,true);
        //方法重载更多用在跨类的调用上
        return call_user_func_array([(new Site),'show'],$arguments);        //返回回到函数处理的结果 将$arguments(array)当做参数传到实例化对象Site的show方法中

    }
    //当访问一个不存在的一个静态方法的时候会自动调用
    public static function __callStatic($name, $arguments)
    {
//        return '方法是:'.$name.'<br>'.'参数列表:'.var_export($arguments,true);
        //方法重载更多用在跨类的调用上
        return call_user_func_array(['Site','add'],$arguments);        //将argunments当做参数传入到Site类中的静态方法add中
    }
}


$web = new Web();

//访问一个不存在的方法
echo $web->show('php中文网','海量资源,公益免费').'<hr>';    

//访问一个不存在的静态方法
echo Web::add(30,50);


Correcting teacher:韦小宝Correction time:2018-11-26 11:12:55
Teacher's summary:嗯!不错!写的很棒!不要骄傲!继续加油吧

Release Notes

Popular Entries