前言:续上寒冬的热火,学习不能停,不能停
(一)final关键字
分类:
1.
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类型,其他类型将会直接报错 }
(四)
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的重载
分类:
1.
<?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.
涉及的魔术方法:
<?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) );
<?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);
<?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);