首頁  >  文章  >  後端開發  >  PHP中的物件導向

PHP中的物件導向

WBOY
WBOY原創
2016-07-30 13:30:021036瀏覽

存取控制(可見性)

PHP的存取控制有 public(公有),protected(受保護)和 private(私有)

被定義為公有的類別成員可以在任何地方被存取。
被定義為受保護的類別成員則可以被其本身以及其子類別和父類別存取。
被定義為私有的類別成員則只能被其定義所在的類別存取。

不能用來修飾class

類屬性不能省略,必須定義為公有,受保護,私有之一。

類別中的方法如果沒有設定這些關鍵字,則該方法預設為公有。

同一個類別的物件即使不是同一個實例也可以互相存取對方的私有與受保護成員。這是由於在這些物件的內部具體實現的細節都是已知的。


屬性

用 ->(物件運算子):$this->property(其中 property 是該屬性名稱)這種方式來存取非靜態屬性。靜態屬性則是用::(雙冒號):self::$property 來存取

$this 是主叫物件的引用


類常數

可以把在類別中始終保持不變的值定義為常數。在定義和使用常數的時候不需要使用$ 符號

常數的值必須是一個定值,不能是變量,類屬性,數學運算的結果或函數調用

用雙冒號::訪問

<code>const constant = 'constant value';
</code>

自動載入類別

很多開發者寫物件導向的應用程式時對每個類別的定義建立一個PHP 原始檔。一個很大的煩惱是必須在每個腳本開頭寫一個長長的包含檔案清單(每個類別一個檔案)。

在 PHP 5 中,不再需要這樣了。可以定義一個 spl_autoload_register() 函數,它會在試圖使用尚未定義的類別時自動呼叫。透過呼叫此函數,腳本引擎在 PHP 出錯失敗前有了最後一個機會載入所需的類別。

<code><?php

// function __autoload($class) {
//     include 'classes/' . $class . '.class.php';
// }

function my_autoloader($class) {
    include 'classes/' . $class . '.class.php';
}

spl_autoload_register('my_autoloader');

// 或者,自 PHP 5.3.0 起可以使用一个匿名函数
spl_autoload_register(function ($class) {
    include 'classes/' . $class . '.class.php';
});

?>
</code>

建構子和析構函式

建構子和析構函式不會被引擎暗中呼叫。要執行父類別的建構子和析構函數,必須在子類別的建構函式體和析構函數體中明確地呼叫parent::__construct(); parent::__destruct()


繼承

除非使用了自動加載,否則一個類別必須在使用之前被定義。如果一個類別擴展了另一個,則父類別必須在子類別之前被聲明。此規則適用於類別繼承其它類別與介面。

繼承使用extends關鍵字


範圍解析操作符(::)

範圍解析操作符(也可稱為Paamayim Nekudotayim)或更簡單地說是一對冒號,可以用於存取靜態冒號,可以用於存取靜態冒號成員,類別常數


Static(靜態)關鍵字

聲明類別屬性或方法為靜態,就可以不實例化類別而直接存取。靜態屬性不能透過一個類別已實例化的物件來存取(但靜態方法可以)。

靜態屬性和方法預設為公有


抽象類

使用關鍵字abstract

任何一個類,如果它裡面至少有一個方法是被聲明為抽象的,那麼這個類就必須被聲明為抽象的。

被定義為抽象的方法只是聲明了其呼叫方式(參數),不能定義其特定的功能實現。

繼承一個抽象類別的時候,子類別必須定義父類別中的所有抽象方法;另外,這些方法的存取控制必須和父類別中一樣(或更為寬鬆)


介面

介面是透過interface關鍵字

介面中定義的所有方法都必須是公有,這是介面的特性

介面中也可以定義常數。介面常數和類別常數的使用完全相同,但是不能被子類別或子介面所覆蓋

要實現一個接口,使用 implements 操作符。類別中必須實作介面中定義的所有方法,否則會報一個致命錯誤。類別可以實作多個接口,用逗號來分隔多個接口的名稱。

介面也可以繼承介面


Traits

自 PHP 5.4.0 起,PHP 實作了程式碼重複使用的一個方法,稱為 traits。

<code><?php
trait ezcReflectionReturnInfo {
    function getReturnType() { /*1*/ }
    function getReturnDescription() { /*2*/ }
}

class ezcReflectionMethod extends ReflectionMethod {
    use ezcReflectionReturnInfo;
    /* ... */
}

class ezcReflectionFunction extends ReflectionFunction {
    use ezcReflectionReturnInfo;
    /* ... */
}
?>
</code>

透過逗號分隔,在 use 聲明列出多個 trait

<code><?php
trait Hello {
    public function sayHello() {
        echo 'Hello ';
    }
}

trait World {
    public function sayWorld() {
        echo 'World';
    }
}

class MyHelloWorld {
    use Hello, World;
    public function sayExclamationMark() {
        echo '!';
    }
}
?>
</code>

魔術方法

__construct()
__destruct()
__call()
__callStatic()
__get()
__set()
__isset()
__unset()
__sleep() serialize() 函數會檢查類別中是否存在一個魔術方法 __sleep()。如果存在,該方法會先被調用,然後再執行序列化操作。
__wakeup() unserialize() 會檢查是否有一個 __wakeup() 方法。如果存在,則會先呼叫 __wakeup 方法
__toString() 用於一個類別被當成字串時應怎樣回應
__invoke() 當嘗試以呼叫函數的方式呼叫一個物件時,__invoke() 方法會被自動呼叫
__set_state() 當呼叫 var_export() 導出類別時,此靜態 方法會被呼叫
__clone()
__debugInfo() var_dump()一個物件時呼叫

這些函數在 PHP 中被稱為」魔術方法」(Magic methods)。在命名自己的類別方法時不能使用這些方法名,除非是想使用其魔術功能。

在賦值不可存取屬性時,__set() 會被呼叫。

讀取不可存取屬性的值時,__get() 會被呼叫。

當對不可存取屬性呼叫 isset() 或 empty() 時,__isset() 會被呼叫。

當對不可存取屬性呼叫 unset() 時,__unset() 會被呼叫。

在物件中呼叫一個不可存取方法時,__call() 會被呼叫。

用靜態方式中呼叫一個不可存取方法時,__callStatic() 會被呼叫。


Final 關鍵字

如果父類別中的方法被宣告為 final,則子類別無法覆寫此方法。如果一個類別被宣告為 final,則不能被繼承。

屬性不能被定義為 final,只有類別和方法才能被定義為 final


物件複製

物件複製可以透過 clone 關鍵字來完成(如果可能,這將呼叫物件的 __clone() 方法)。物件中的 __clone() 方法不能直接呼叫。


物件比較

當使用比較運算子(==)比較兩個物件變數時,比較的原則是:如果兩個物件的屬性和屬性值都相等,而兩個物件是同一類別的實例,那麼這兩個物件變數相等。

而如果使用全等運算子(===),這兩個物件變數一定要指向某個類別的同一個實例(即同一個物件)。


型限制

PHP 5 可以使用型別約束。函數的參數可以指定必須為物件(在函數原型裡面指定類別的名字),接口,數組(PHP 5.1 起)或 callable(PHP 5.4 起)。不過如果使用 NULL 作為參數的預設值,那麼在呼叫函數的時候依然可以使用 NULL 作為實參。

類型約束不能用於標量類型如 int 或 string。 Traits 也不允許。

類型約束不只是用在類別的成員函數裡,也能使用在函數裡


物件序列化

所有php裡面的值都可以使用函數serialize()來傳回一個包含位元組流的字串來表示。 unserialize()函數能夠重新把字串變回php原來的值。 序列化一個物件將會保存物件的所有變量,但是不會保存物件的方法。


版權聲明:本文為部落客原創文章,未經部落客允許不得轉載。

以上就介紹了PHP中的面向對象,包括了方面的內容,希望對PHP教程有興趣的朋友有幫助。

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn