面向对象(三)

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

(一)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这条路,当你懂得越多的时候,那么你不懂的也就会越多了.
原文地址:https://www.cnblogs.com/learningPHP-students2018/p/10198612.html