面向物件(三)
阿新 • • 發佈:2018-12-30
前言:續上寒冬的熱火,學習不能停,不能停
(一)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);