• 面向对象(三)


    前言:续上寒冬的热火,学习不能停,不能停

    (一)final关键字

      分类:

      1.使用final关键字定义的类,我们称其为 final类或最终类

      2.使用final关键字定义的类中的方法,我们称其为 final方法或最终方法

      定义:

    //使用final关键字申明类
    final  class  类名{
        类成员
    }
    //特点
    不能被别的类继承了
    //使用final关键字申明方法
    final  public/protected [static] function  方法名(){
        方法体
    }
    //特点
    不能被重写

    (二) 抽象类

      表现:

    //使用abstract申明一个抽象类
    abstract  class  类名{
        抽象类成员
    }

      组成:

      1.普通类的所有的成员

      2.抽象方法

    <?php
    
    #定义一个抽象类
    abstract class A{
    
        #普通类的所有成员
        public $var1;
        public static $var2;
        const PATH='./source/';
        public function f1(){ 
            echo 'f1'; 
        }
        public static function f2(){ 
            echo 'static_f2'; 
        }
    
        #抽象方法  比普通方法多了个abstract关键字,少了方法体
        abstract public function f3($v1, $v2);
    }

      特点:

      1.抽象类只能被继承,不能被直接实例化为对象,但是抽象类中的静态成员和类常量都能够正常使用;

    <?php
    
    #定义一个抽象类
    abstract class A{
    
        #普通类的所有成员
        public $var1='var1';
        public static $var2='var2';
        const PATH='./source/';
        public function f1(){ 
            echo 'f1'; 
        }
        public static function f2(){ 
            echo 'static_f2'; 
        }
    }
    
    var_dump( A::$var2 ); echo '<br/>'; //调用抽象类中的静态成员属性
    var_dump( A::PATH ); echo '<br/>'; //调用抽象类中的类常量
    A::f2();//调用抽象类中的静态方法
    
    $a1 = new A;//抽象类不能被用来实例化为对象

      2.抽象类如果被普通类所继承,那么抽象类中的抽象方法必须全部被实现;

    <?php
    
    #定义一个抽象类
    abstract class A{
    
        #普通类的所有成员
        public $var1='var1';
    
        #抽象方法
        abstract public function f1($v1);
        abstract public function f2($v1, $v2, $v3);
        abstract protected function f3();
    }
    
    class B extends A{
    
        //实现抽象类中的抽象方法   去掉abstract关键字,补上方法的方法体
        public function f1($v1){
        
        }
    
        public function f2($v1, $v2, $v3){ 
            
        }
    
        protected function f3(){ 
            
        }
    }

      3.抽象类还可以被抽象类所继承,如果被抽象类所继承,那么被继承的那个抽象类中其抽象方法可以不被实现;

    <?php
    
    #定义一个抽象类
    abstract class A{
    
        #普通类的所有成员
        public $var1='var1';
    
        #抽象方法
        abstract public function f1($v1);
        abstract public function f2($v1, $v2, $v3);
        abstract protected function f3();
    }
    
    abstract class B extends A{
    
    }

    (三) PHP中的接口

      区别:PHP中的接口指的不是我们平时听到的支付接口,物流接口之类的api,而是特指PHP中的一种语法;

      表现:

    interface  接口名{
        接口成员
    }

      成员:

      1.接口常量

      2.接口抽象方法 

      定义方式:

    <?php
    
    #定义一个PHP中的接口
    interface inter1{
        #接口成员
        //接口常量
        const PATH='./source';
    
        //接口抽象方法   比抽象类中的抽象方法少了abstract关键字
        public function f1($v1, $v2);
    }

      特点:

      1.接口需要使用implements关键字来实现;

    <?php
    
    #定义一个PHP中的接口
    interface inter1{
    
        #接口成员
        //接口常量
        const PATH='./source';
    }
    
    //接口需要使用关键字implements来实现
    class A implements inter1{
    
    }

      2.接口可以被多实现

    <?php
    
    #定义一个PHP中的接口
    interface inter1{
    
        #接口成员
        //接口常量
        const PATH='./source';
    }
    
    interface inter2{
        
    }
    
    //接口可以一次性被实现多个
    class A implements inter1, inter2{
    
    }

      3.接口如果被普通类所实现,那么,接口中的所有接口抽象方法都要被全部实现;

    <?php
    
    #定义一个PHP中的接口
    interface inter1{
    
        #接口成员
        //接口常量
        const PATH='./source';
    
        //接口抽象方法   比抽象类中的抽象方法少了abstract关键字
        public function f1($v1, $v2);
        public function f2($v1, $v2);
    }
    
    class A implements inter1{
    
        //只要补上方法体的大括号就叫做实现了接口的抽象方法
        public function f1($v1, $v2){ 
            
        }
    
        public function f2($v1, $v2){ 
            
        }
    }

      4.接口还可以被抽象类所实现,如果被抽象类实现,那么接口中的接口抽象方法可以不被实现

    <?php
    
    #定义一个PHP中的接口
    interface inter1{
    
        #接口成员
        //接口常量
        const PATH='./source';
    
        //接口抽象方法   比抽象类中的抽象方法少了abstract关键字
        public function f1($v1, $v2);
        public function f2($v1, $v2);
    }
    
    abstract class A implements inter1{
    
    }

      5.接口中的接口抽象方法只能是public类型;

    <?php
    
    #定义一个PHP中的接口
    interface inter1{
    
        #接口成员
        //接口常量
        const PATH='./source';
    
        //接口抽象方法   比抽象类中的抽象方法少了abstract关键字
        //protected function f1($v1, $v2);
        //private function f1($v1, $v2);
        public function f1($v1, $v2);//接口中的接口抽象方法只能是public类型,其他类型将会直接报错
    }

    (四) 静态延时绑定

      引言:静态延时绑定是PHP5.3之后才出现的特性。

      静态延时绑定需要用到的关键字是:static

      static关键字的意思:表示哪个类调用,就代表那个类。

    <?php
    
    class StaticDemo{
    
        public static $var1='var1';
    
        public static function f1(){ 
            //访问子类中的$var2属性
            var_dump( Demo::$var2 ); echo '<br/>';
            var_dump( static::$var2 ); echo '<hr/>';
        }
    }
    
    class Demo extends StaticDemo{
        
        public static $var2='var2';
    
        public function f2(){ 
            //调用父类中的$var1属性
            var_dump( parent::$var1 ); echo '<br/>';
            var_dump( StaticDemo::$var1 ); echo '<br/>';
            var_dump( self::$var1 ); echo '<br/>';
            var_dump( Demo::$var1 ); echo '<br/>';
            var_dump( static::$var1 ); echo '<hr/>';echo '<hr/>';
    
            //调用本类中的$var2属性
            var_dump( self::$var2 ); echo '<br/>';
            var_dump( Demo::$var2 ); echo '<br/>';
            var_dump( static::$var2 );
        }
    }

    (五) PHP的重载

      概念:PHP中的重载,指的是当访问一个不可访问(不存在的成员或存在却不能访问的成员)的成员时,如何来进行处理,这个处理过程就是PHP中的重载。

      分类:

      1.默认的重载 当访问一个不可访问的成员时,PHP默认的处理过程

    <?php
    
    class OverloadDemo{
    
        protected $var1='var1';
    
        protected function f1($v1){ //protected类型  的  非静态方法
            echo $v1; 
        }
    
        private static function f2($v1){ //private类型  的  静态方法
            echo $v1; 
        }
    }
    
    $obj = new OverloadDemo;
    var_dump( $obj ); echo '<br/>';
    $obj->name = 'zhangsan';//添加一个属性,属于访问到一个不可访问的成员中的访问到了一个不存在的成员,PHP默认帮我们把这个属性添加进对象里了
    var_dump( $obj ); echo '<hr/>';
    
    //var_dump( $obj->var1 ); //当我们访问到一个不可访问的成员属性时(属于访问到一个存在但是不能访问的成员的情况),PHP默认直接报错
    
    //unset($obj->var1);//当我们删除一个不可访问的成员时(属于删除到一个存在但是不能访问的成员的情况),PHP默认直接报错
    
    var_dump( isset($obj->var1) ); echo '<hr/>';//当判断一个不可访问的成员是否存在时(属于存在但是不能访问的情况),PHP默认返回false
    
    //$obj->f1(100);//当访问到一个不可访问的非静态方法时(属于存在但是不能访问的情况),PHP默认直接报错
    
    OverloadDemo::f2();//当访问到一个不可访问的静态方法时(属于存在但是不能访问的情况),PHP默认直接报错

      2.自定义重载 当访问一个不可访问的成员时,开发者自定义的处理过程

      分为两类:(非静态)属性的重载和方法的重载

      属性的重载涉及的魔术方法:

      __get(属性名) 当获取一个不可访问的(非静态)成员属性值时,进行自定义的处理

    <?php
    
    class __getDemo{
    
        protected $name='郭嘉';
    
        //定义__get魔术方法   $v表示之后获取的不可访问的成员属性的属性名
        public function __get($v){ 
            
            if( $v=='name' ){
                return $this->name;
            }elseif( $v=='var1' ){
                return '就不给你看';
            }
        }
    }
    
    $obj = new __getDemo;
    var_dump( $obj ); echo '<hr/>';
    
    //           $obj->name = $obj->__get('name');
    var_dump( $obj->name ); echo '<br/>';
    var_dump( $obj->var1 ); 

      __set(属性名, 属性值) 当设置一个不可访问的(非静态)成员属性值时,进行自定义的处理

    <?php
    
    class __setDemo{
    
        protected $name='王翦';
        private $age=18;
    
        //__set魔术方法
        public function __set($v1, $v2){ 
            
            if( $v1=='name' ){
                $this->name = $v2;
            }elseif( $v1=='age' ){
                $this->age = 100;
            }else{
                echo '不允许添加额外的属性哦!'; 
            }
        }
    }
    
    $obj = new __setDemo;
    var_dump( $obj ); echo '<br/>';
    $obj->name = '王贲';
    var_dump( $obj ); echo '<br/>';
    $obj->age = 3.14;
    var_dump( $obj ); echo '<br/>';
    $obj->height = 3.16;
    echo '<br/>';
    var_dump( $obj ); 

      __unset(属性名) 当删除一个不可访问的(非静态)成员属性时,进行自定义的处理

    class __unsetDemo{
    
        protected $name='梦奇';
        private $age=19;
    
        //__unset魔术方法   需要指定一个必填参数,是不可访问的成员属性属性名
        public function __unset($v1){ 
            
            if( $v1=='age' ){
                unset($this->age);
                return true;  //不要指定返回值,即使指定了返回值也无效
            }else{
                echo '再删!给你小拳拳哦!'; 
            }
        }
    }
    
    $obj = new __unsetDemo;
    var_dump( $obj ); echo '<br/>';
    unset($obj->name); echo '<br/>';
    var_dump( $obj ); echo '<br/>';
    unset($obj->age); echo '<br/>';
    var_dump( $obj ); 

      __isset(属性名) 当判断一个不可访问的(非静态)成员属性是否存在时,进行自定义的处理

    <?php
    
    class __issetDemo{
    
        protected $name='二师兄';
        private $age=19;
    
        //__isset魔术方法  需要指定一个必填参,是不可访问的成员属性的属性名
        public function __isset($v1){ 
            
            if( $v1=='name' ){
                return true;
            }else{
                return false;
            }
        }
    }
    
    $obj = new __issetDemo;
    var_dump( isset($obj->name) ); echo '<br/>';
    var_dump( isset($obj->age) ); echo '<br/>';
    var_dump( isset($obj->var1) ); 

      __call(方法名, 传递给方法的参数) 当访问一个不可访问的(非静态)成员方法时,进行自定义处理

    <?php
    
    class __callDemo{
    
        private function f1($v1, $v2){ 
            echo $v1; 
        }
    
        //__call魔术方法  需要2个必填参,第一个参数是不可访问的方法的方法名;第二个参数是传递给该方法的所有参数所形成的数组
        public function __call($v1, $v2){ 
            
            if( $v1=='f1' ){
                $this->f1($v2[0], $v2[1]);
            }else{
                echo '再来就给你小拳拳哟~'; 
            }
        }
    }
    
    $obj = new __callDemo;
    $obj->f1('hello', 10);// 相当于PHP自动这样做:$obj->__call('hello', 10);

      __callstatic(方法名, 传递给方法的参数) 当访问一个不可访问的(静态)成员方法时,进行自定义处理

    <?php
    
    class __callStaticDemo{
    
        private static function f1($v1, $v2){ 
            echo $v1; 
        }
    
        //__callstatic魔术方法  需要2个必填参,第一个参数是不可访问的方法的方法名;第二个参数是传递给该方法的所有参数所形成的数组
        public static function __callstatic($v1, $v2){ 
            
            if( $v1=='f1' ){
                self::f1($v2[0], $v2[1]);
            }else{
                echo '再来就给你小拳拳哟~'; 
            }
        }
    }
    
    __callStaticDemo::f1('hi~', 10);
    IT这条路,当你懂得越多的时候,那么你不懂的也就会越多了.
  • 相关阅读:
    那些年,加班搞过的需求...
    在基于nuxt的移动端页面中引用mint UI的popup组件之父子组件传值
    nuxt下运行项目时内存溢出(out of memory)的一种情况
    转载的
    VUE旅程(2)
    用windbg+sos找出程序中谁占用内存过高,谁占用CPU过高(转载)
    分块算法总结(持续更新ing)
    【MATLAB建模学习实录【三】】插值与拟合、数据处理
    【MATLAB建模学习实录【二】】非线性规划函数模型板子
    【MATLAB建模学习实录【一】】MATLAB求解线性规划模板
  • 原文地址:https://www.cnblogs.com/learningPHP-students2018/p/10198612.html
Copyright © 2020-2023  润新知