php面向對象 封裝繼承多態 接口、重載、抽象類、最終類總結
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面向對象 封裝繼承多態 接口、重載、抽象類、最終類總結