1. 程式人生 > >php面向對象 封裝繼承多態 接口、重載、抽象類、最終類總結

php面向對象 封裝繼承多態 接口、重載、抽象類、最終類總結

clas rdquo 之前 結合 單例模式 say erro 版權 rac

1、面向對象 封裝繼承多態 接口、重載、抽象類、最終類

面向對象 封裝繼承多態

首先,在解釋面向對象之前先解釋下什麽是面向對象?

[面向對象]
1、什麽是類?
具有相同屬性(特征)和方法(行為)的一系列個體的集合,類是一個抽象的概念
2、什麽是對象?
從類中拿到的具有具體屬性值得個體,稱為對象,對象是一個具體的個體

所以,面向對象即我們專註對象來處理問題,通過從一個個具有屬性和功能的類中拿到對象來處理問題。

下面我們再來細說下面向對象的三大特征:繼承/封裝/多態

一、繼承

在PHP中我們主要通關Extends關鍵字來實現繼承 ->class Student extends Person{}

下面是幾個比較重要的註意事項:

①子類只能繼承父類的非私有屬性。
②子類繼承父類後,相當於將父類的屬性和方法copy到子類,可以直接使用$this調用該屬性;
③PHP只能單繼承,不支持一個類繼承多個類。但是一個類可以進行多層繼承(即A繼承於B,而C又繼承於A,C通過A間接繼承了B)

二、封裝

類實現封裝是為了不讓外面的類隨意的修改一個類的成員變量,所以在定義一個類的成員的時候,我們使用private關鍵字設置這個成員的訪問權限

只能被這個類的其他成員方法調用,而不能被其他類中的方法調用,即通過本類中提供的方法來訪問本類中的私有屬性。

①所以在該類中我們會提供一個訪問私有屬性的方法

②然後我們一般會定義兩個方法來實現對一個變量的操作,即:get()與set()方法。

代碼示例如下:

class Person{
        private $name;
        private $age;
        
        public function __construct($name,$age){
            $this->name = $name;
            $this->age = $age;
        }
        function setAge($age){
            if($age>=0&&$age<=120){
                
$this->age = $age; }else{ error_log("年齡設置有誤!"); } } function getAge(){ return $this->age; } public function say(){ echo "我叫{$this->name},我今年{$this->age}歲了"; } function __get($name){ switch ($name) { case ‘name‘: return $this ->$name."這是讀取時加的文字"; case ‘age‘: return "0".$this ->$name; default: return $this ->$name; } } function __set($key,$value){ if($key=="name"){ $this->$key = $value."這是設置時加的文字<br>"; }else{ $this->$key = $value; } } function __isset($name){ return isset($this->$name); } function __unset($name){ if($name=="age"){ return; } unset($this->$name); } } $zhangsan = new Person("zhangsan",14); $zhangsan->setAge(12); echo $zhangsan->getAge()."<br>"; var_dump(isset($zhangsan->name)); unset($zhangsan->age); echo $zhangsan->age;

三、多態

什麽是多態?

一個類,被多個子類繼承,如果這個類的某個方法,在多個子類中,表現出不同的功能,我們稱這種行為為多態。(同一個類的不同子類表現出不同的形態)

那麽我們如何來實現多態呢?

子類繼承父類 ->子類重寫父類方法 ->父類引用指向子類對象

abstract class Person
{
//註:父類使用abstract關鍵字修飾   
abstract function say(); } class Chinese extends Person
{
  //註:子類重寫父類方法   
function say(){     echo "我是中國人<br>";   } }
class English extends Person
{
  //註:子類重寫父類方法   
function say(){     echo "我是英國人";   } } $zhangsan = new Chinese(); $zhangsan->say(); $z = new English(); $z->say(); Person $p = new Chinese(); //註:父類引用指向子類對象

上述代碼中,兩個子類都是繼承自同一父類,但因為都重寫了父類的方法,表現出了不同的形態

* 四、單例設計模式


單例模式也叫單態模式
可以保證一個類只能有一個對象實例
實現要點:
①構造函數私有化,不允許使用new關鍵字創建對象。
②對外提供獲取對象的方法,在方法中判斷對象是否為空,如果為空則創建對象並返回,如果不為空則直接返回
③實例對象的屬性以及獲取對象的方法必須都是靜態的。
④之後,創建對象只能使用我們提供的靜態方法。

示例代碼如下:

class Singleton
{   
static public $Single = null;   private function __construct(){}   static function getSingle()
  {     
if(!self::$Single){       self::$Single = new Singleton();//self代指類名 new Singleton()和newself()是完全一樣的     }     return self::$Single;   }   function __destruct()
  {     
echo "我被銷毀了<br>";   }
}
$s1 = Singleton::getSingle(); $s1 = Singleton::getSingle(); $s1 = Singleton::getSingle();

抽象類、抽象方法、重載、接口

抽象類

定義:一個抽象的不能被實例化的類。

定義形式(abstract關鍵字):

abstract class 類名{

// ...

}

抽象方法

定義:一個只有方法頭,沒有方法體的方法

定義形式(用abstract修飾方法)

abstract class 類名{

abstract function 方法名(形參列表); // 沒有方法體,結尾分號不能省略

}

抽象類和抽象方法的細節:

一個抽象方法必須在抽象類中,即方法為抽象的,那麽其所在的類也不是是抽象的;

抽象類中可以沒有抽象方法;

子類繼承了父類,那麽要麽實現(“重寫”)父類的抽象方法,要麽在次定義為抽象的。

重載

含義:在“通常面向對象語言”中是指一個類可以名字相同但形參不同的方法的現象(如java)。

如:

class A{

function f(){

}

function f($a){

}

function f($a,$b){

}

}

php中的重載

含義:是指當對一個對象或類使用其未定義的屬性或方法的時候,其中的一些“處理機制”。

屬性重載:

含義:對一個對象的不存在的屬性進行使用的時候,這個類種預先設定好的應對方法(處理機制)

屬性,本質就是一個變量,其有4個操作:

取值:當對一個對象的不存在的屬性進行“取值”的時候,就會自動調用方法:__get();

賦值:當對一個對象的不存在的屬性進行“取值”的時候,就會自動調用方法:__set();

判斷(isset):當對一個對象的不存在的屬性進行“判斷”的時候,就會自動調用方法:__isset();

判斷(isset):當對一個對象的不存在的屬性進行“判斷”的時候,就會自動調用方法:__unset()。

__set($屬性名,值):

含義:當對一個對象的不存在屬性進行“賦值”的時候就會自動調用這個內部的魔術方法,它有兩個形參,分別代表對不存在的屬性進行賦值的時候的“屬性名”和“屬性值”。

 這個方法結合__get()方法,往往可以使我們定義的類,就有一種“可簡便擴展屬性”的特性,即類(或對象)的屬性,可以更為方便自由,如下所示:

class A{

protected $prop_list = array();

function __set($p,$v){

$this->prop_list[$p] = $v;

}

function __get($p){

return $this->prop_list[$p];

}

}

__isset()

含義:當對一個對象的不存在屬性進行“判斷”的時候就會自動調用這個內部的魔術方法。

__unset()

含義:當對一個對象的不存在屬性進行“銷毀”的時候就會自動調用這個內部的魔術方法。

方法重載

當對一個對象的不存在的實例方法進行“調用”的時候會自動調用類中的__call()這個魔術方法;

當對一個對象的不存在的靜態方法進行“調用”的時候會自動調用類中的__callstatic()這個魔術方法。

php中實現通常的面向對象語言的“方法重載”(利用__call()和__callstatic()方法),如:

<?php
class A{
function __call($methodName,$arguments){
switch ($methodName)
{
case ‘f1‘: // 調用了f1這個不存在的方法 # 調用了方法名為f1的這一系列重載方法 if(count($arguments) == 0){ // 這裏拿這些參數做這個方法的事情... }else if(count($arguments) == 1){ // 這裏拿這些參數做這個方法的事情... }else if(count($arguments) == 2){ // 這裏拿這些參數做這個方法的事情... }else if(count($arguments) == 3){ // 這裏拿這些參數做這個方法的事情... } // ... break; case ‘f2‘: // 調用了f2這個不存在的方法 # 調用了方法名為f2的這一系列重載方法 if(count($arguments) == 0){ // 這裏拿這些參數做這個方法的事情... }else if(count($arguments) == 1){ // 這裏拿這些參數做這個方法的事情... }else if(count($arguments) == 2){ // 這裏拿這些參數做這個方法的事情... }else if(count($arguments) == 3){ // 這裏拿這些參數做這個方法的事情... } // ... break; default: break; } } } ?>

接口

定義形式

interface 接口名{

常量1;

常量2;

...

抽象方法1;

抽象方法2;

...

}

說明:

接口中只有常量(接口常量)和抽象方法兩種成員;

接口常量的使用形式為:接口名稱::常量名稱;

接口中的抽象方法,不要使用abstract修飾,也需要使用訪問控制修飾符,因為其天然就是Public;

php中接口和類一樣也可以繼承(接口繼承接口)。

還談php和java面向對象

相同點:

抽象類和抽象方法,及它們之間的細節都一樣;

php的接口和java的接口都一樣。

不同點:

重載不一樣,php重載和其他面向對象語言的重載不同,而java和其他面向對對象語言的重載一樣。

最終類final class:

在定義一個類的時候,在class關鍵字前面使用final關鍵,則表示該類“不可繼承”(禁止繼承);

如下:

final class 類名{

  //類成員定義。。

}

技術分享圖片

最終方法

就是在方法定義的前面,使用關鍵字final,表示該方法“不可覆蓋”——禁止覆蓋。

抽象類
定義:一個抽象的不能被實例化的類。定義形式(abstract關鍵字):
abstract class 類名{ // ...}123抽象方法
定義:一個只有方法頭,沒有方法體的方法
定義形式(用abstract修飾方法)
abstract class 類名{ abstract function 方法名(形參列表); // 沒有方法體,結尾分號不能省略}123抽象類和抽象方法的細節:
一個抽象方法必須在抽象類中,即方法為抽象的,那麽其所在的類也不是是抽象的;抽象類中可以沒有抽象方法;子類繼承了父類,那麽要麽實現(“重寫”)父類的抽象方法,要麽在次定義為抽象的。重載
含義:在“通常面向對象語言”中是指一個類可以名字相同但形參不同的方法的現象(如java)。
如:

class A{   
  function f(){}   
  function f($a){}   
   function f($a,$b){}
}1234567891011php中的重載

含義:是指當對一個對象或類使用其未定義的屬性或方法的時候,其中的一些“處理機制”。
屬性重載:
含義:對一個對象的不存在的屬性進行使用的時候,這個類種預先設定好的應對方法(處理機制)屬性,本質就是一個變量,其有4個操作:
取值:當對一個對象的不存在的屬性進行“取值”的時候,就會自動調用方法:__get();賦值:當對一個對象的不存在的屬性進行“取值”的時候,就會自動調用方法:__set();判斷(isset):當對一個對象的不存在的屬性進行“判斷”的時候,就會自動調用方法:__isset();判斷(isset):當對一個對象的不存在的屬性進行“判斷”的時候,就會自動調用方法:__unset()。__set($屬性名,值):
含義:當對一個對象的不存在屬性進行“賦值”的時候就會自動調用這個內部的魔術方法,它有兩個形參,分別代表對不存在的屬性進行賦值的時候的“屬性名”和“屬性值”。
 這個方法結合__get()方法,往往可以使我們定義的類,就有一種“可簡便擴展屬性”的特性,即類(或對象)的屬性,可以更為方便自由,如下所示:
class A{ protected $prop_list = array(); function __set($p,$v){ $this->prop_list[$p] = $v; } function __get($p){ return $this->prop_list[$p]; }}123456789__isset()
含義:當對一個對象的不存在屬性進行“判斷”的時候就會自動調用這個內部的魔術方法。__unset()
含義:當對一個對象的不存在屬性進行“銷毀”的時候就會自動調用這個內部的魔術方法。方法重載
當對一個對象的不存在的實例方法進行“調用”的時候會自動調用類中的__call()這個魔術方法;
當對一個對象的不存在的靜態方法進行“調用”的時候會自動調用類中的__callstatic()這個魔術方法。
php中實現通常的面向對象語言的“方法重載”(利用__call()和__callstatic()方法),如:

<?php
class A{
    function __call($methodName,$arguments)
{
    switch ($methodName) {
case ‘f1‘:
      // 調用了f1這個不存在的方法
      // 調用了方法名為f1的這一系列重載方法
      if(count($arguments) == 0){
      // 這裏拿這些參數做這個方法的事情...
      }else if(count($arguments) == 1){
      // 這裏拿這些參數做這個方法的事情...
      }else if(count($arguments) == 2){
      // 這裏拿這些參數做這個方法的事情...
      }else if(count($arguments) == 3){
      // 這裏拿這些參數做這個方法的事情...
      }
    // ...
    break;
  case ‘f2‘:
// 調用了f2這個不存在的方法
# 調用了方法名為f2的這一系列重載方法
  if(count($arguments) == 0){
// 這裏拿這些參數做這個方法的事情...
  }else if(count($arguments) == 1){
// 這裏拿這些參數做這個方法的事情...
}else if(count($arguments) == 2){
    // 這裏拿這些參數做這個方法的事情...
}else if(count($arguments) == 3){
   // 這裏拿這些參數做這個方法的事情...
}
// ...
break;
default:
break;
}
}}
?>


定義形式
interface 接口名{ 常量1; 常量2; ... 抽象方法1; 抽象方法2; ...}12345678說明:
接口中只有常量(接口常量)和抽象方法兩種成員;接口常量的使用形式為:接口名稱::常量名稱;接口中的抽象方法,不要使用abstract修飾,也需要使用訪問控制修飾符,因為其天然就是Public;php中接口和類一樣也可以繼承(接口繼承接口)。還談php和java面向對象
相同點:
抽象類和抽象方法,及它們之間的細節都一樣;php的接口和java的接口都一樣。不同點:
重載不一樣,php重載和其他面向對象語言的重載不同,而java和其他面向對對象語言的重載一樣。--------------------- 作者:宿罪 來源:CSDN 原文:https://blog.csdn.net/ydxlt/article/details/50667454 版權聲明:本文為博主原創文章,轉載請附上博文鏈接!

php面向對象 封裝繼承多態 接口、重載、抽象類、最終類總結