
- PHP 教程
- PHP - 首頁
- PHP - 簡介
- PHP - 安裝
- PHP - 歷史
- PHP - 特性
- PHP - 語法
- PHP - Hello World
- PHP - 註釋
- PHP - 變數
- PHP - Echo/Print
- PHP - var_dump
- PHP - $ 和 $$ 變數
- PHP - 常量
- PHP - 魔術常量
- PHP - 資料型別
- PHP - 型別轉換
- PHP - 型別雜耍
- PHP - 字串
- PHP - 布林值
- PHP - 整數
- PHP - 檔案與 I/O
- PHP - 數學函式
- PHP - Heredoc 和 Nowdoc
- PHP - 複合型別
- PHP - 檔案包含
- PHP - 日期和時間
- PHP - 標量型別宣告
- PHP - 返回型別宣告
- PHP 運算子
- PHP - 運算子
- PHP - 算術運算子
- PHP - 比較運算子
- PHP - 邏輯運算子
- PHP - 賦值運算子
- PHP - 字串運算子
- PHP - 陣列運算子
- PHP - 條件運算子
- PHP - 展開運算子
- PHP - 空值合併運算子
- PHP - 比較運算子
- PHP 控制語句
- PHP - 決策
- PHP - If...Else 語句
- PHP - Switch 語句
- PHP - 迴圈型別
- PHP - For 迴圈
- PHP - Foreach 迴圈
- PHP - While 迴圈
- PHP - Do...While 迴圈
- PHP - Break 語句
- PHP - Continue 語句
- PHP 函式
- PHP - 函式
- PHP - 函式引數
- PHP - 按值傳遞
- PHP - 按引用傳遞
- PHP - 預設引數
- PHP - 命名引數
- PHP - 可變引數
- PHP - 返回值
- PHP - 傳遞函式
- PHP - 遞迴函式
- PHP - 型別提示
- PHP - 變數作用域
- PHP - 嚴格型別
- PHP - 匿名函式
- PHP - 箭頭函式
- PHP - 可變函式
- PHP - 區域性變數
- PHP - 全域性變數
- PHP 超全域性變數
- PHP - 超全域性變數
- PHP - $GLOBALS
- PHP - $_SERVER
- PHP - $_REQUEST
- PHP - $_POST
- PHP - $_GET
- PHP - $_FILES
- PHP - $_ENV
- PHP - $_COOKIE
- PHP - $_SESSION
- PHP 檔案處理
- PHP - 檔案處理
- PHP - 開啟檔案
- PHP - 讀取檔案
- PHP - 寫入檔案
- PHP - 檔案是否存在
- PHP - 下載檔案
- PHP - 複製檔案
- PHP - 追加檔案
- PHP - 刪除檔案
- PHP - 處理 CSV 檔案
- PHP - 檔案許可權
- PHP - 建立目錄
- PHP - 列出檔案
- 面向物件 PHP
- PHP - 面向物件程式設計
- PHP - 類和物件
- PHP - 建構函式和解構函式
- PHP - 訪問修飾符
- PHP - 繼承
- PHP - 類常量
- PHP - 抽象類
- PHP - 介面
- PHP - 特性
- PHP - 靜態方法
- PHP - 靜態屬性
- PHP - 名稱空間
- PHP - 物件迭代
- PHP - 封裝
- PHP - Final 關鍵字
- PHP - 過載
- PHP - 克隆物件
- PHP - 匿名類
- PHP Web 開發
- PHP - Web 概念
- PHP - 表單處理
- PHP - 表單驗證
- PHP - 表單郵件/URL
- PHP - 完整表單
- PHP - 檔案包含
- PHP - GET 和 POST
- PHP - 檔案上傳
- PHP - Cookies
- PHP - Sessions
- PHP - Session 選項
- PHP - 傳送郵件
- PHP - 過濾輸入
- PHP - Post-Redirect-Get (PRG)
- PHP - 快閃記憶體訊息
- PHP 高階
- PHP - MySQL
- PHP.INI 檔案配置
- PHP - 陣列解構
- PHP - 編碼規範
- PHP - 正則表示式
- PHP - 錯誤處理
- PHP - Try...Catch
- PHP - Bug 除錯
- PHP - 適用於 C 開發人員
- PHP - 適用於 PERL 開發人員
- PHP - 框架
- PHP - Core PHP 與框架
- PHP - 設計模式
- PHP - 過濾器
- PHP - JSON
- PHP - 異常
- PHP - 特殊型別
- PHP - 雜湊
- PHP - 加密
- PHP - is_null() 函式
- PHP - 系統呼叫
- PHP - HTTP 認證
- PHP - 交換變數
- PHP - Closure::call()
- PHP - 過濾的 unserialize()
- PHP - IntlChar
- PHP - CSPRNG
- PHP - 預期
- PHP - Use 語句
- PHP - 整數除法
- PHP - 已棄用的特性
- PHP - 已刪除的擴充套件和 SAPI
- PHP - PEAR
- PHP - CSRF
- PHP - FastCGI 程序
- PHP - PDO 擴充套件
- PHP - 內建函式
- PHP 有用資源
- PHP - 速查表
- PHP - 問答
- PHP - 快速指南
- PHP - 線上編譯器
- PHP - 有用資源
- PHP - 討論
PHP 面向物件程式設計
我們可以想象我們的宇宙是由不同的物體組成的,比如太陽、地球、月亮等等。同樣,我們可以想象我們的汽車是由不同的物體組成的,比如車輪、方向盤、齒輪等等。同樣,存在面向物件程式設計的概念,它假設一切都是物件,並使用不同的物件來實現軟體。
面向物件概念
在我們深入瞭解之前,讓我們定義一些與面向物件程式設計相關的術語。
類 - 這是程式設計師定義的資料型別,它包括區域性函式和區域性資料。您可以將類視為建立許多相同型別(或類)物件的模板。
物件 - 類定義的資料結構的單個例項。您只定義一次類,然後建立許多屬於它的物件。物件也稱為例項。
成員變數 - 這些是在類中定義的變數。此資料對類外部不可見,並且可以透過成員函式訪問。一旦建立物件,這些變數就被稱為物件的屬性。
成員函式 - 這些是在類中定義的函式,用於訪問物件資料。
繼承 - 當一個類透過繼承父類的現有函式來定義時,它被稱為繼承。這裡子類將繼承父類所有或部分成員函式和變數。
父類 - 被另一個類繼承的類。這也被稱為基類或超類。
子類 - 從另一個類繼承的類。這也被稱為子類或派生類。
多型性 - 這是一個面向物件的概念,其中相同的函式可以用於不同的目的。例如,函式名將保持不變,但它可以接受不同數量的引數並執行不同的任務。
過載 - 多型性的一種型別,其中某些或所有運算子具有不同的實現,具體取決於其引數的型別。類似地,函式也可以透過不同的實現進行過載。
資料抽象 - 任何隱藏(抽象)實現細節的資料表示。
封裝 - 指的是一個概念,我們將所有資料和成員函式封裝在一起以形成一個物件。
建構函式 - 指的是一種特殊型別的函式,每當從類中形成物件時,它都會自動被呼叫。
解構函式 - 指的是一種特殊型別的函式,每當物件被刪除或超出範圍時,它都會自動被呼叫。
定義 PHP 類
在 PHP 中定義新類的通用形式如下所示:
<?php class phpClass { var $var1; var $var2 = "constant string"; function myfunc ($arg1, $arg2) { [..] } [..] } ?>
以下是每行的描述:
特殊的class形式,後跟要定義的類的名稱。
一組花括號,包含任意數量的變數宣告和函式定義。
變數宣告以特殊的var形式開頭,後跟傳統的$變數名;它們也可以具有對常量的初始賦值。
函式定義看起來很像獨立的 PHP 函式,但它們是區域性於類的,將用於設定和訪問物件資料。
示例
這是一個定義 Books 型別的類的示例:
<?php class Books { /* Member variables */ var $price; var $title; /* Member functions */ function setPrice($par){ $this->price = $par; } function getPrice(){ echo $this->price ."<br/>"; } function setTitle($par){ $this->title = $par; } function getTitle(){ echo $this->title ." <br/>"; } } ?>
變數$this是一個特殊變數,它指的是同一個物件,即自身。
在 PHP 中建立物件
定義類後,您可以根據該類型別建立任意數量的物件。以下是如何使用new運算子建立物件的示例。
$physics = new Books; $maths = new Books; $chemistry = new Books;
這裡我們建立了三個物件,這些物件彼此獨立,它們將分別存在。接下來,我們將瞭解如何訪問成員函式和處理成員變數。
呼叫成員函式
建立物件後,您將能夠呼叫與該物件相關的成員函式。一個成員函式只能處理相關物件的成員變數。
以下示例顯示瞭如何透過呼叫成員函式為三本書設定標題和價格。
$physics->setTitle( "Physics for High School" ); $chemistry->setTitle( "Advanced Chemistry" ); $maths->setTitle( "Algebra" ); $physics->setPrice( 10 ); $chemistry->setPrice( 15 ); $maths->setPrice( 7 );
現在,您可以呼叫另一個成員函式來獲取在上例中設定的值:
$physics->getTitle(); $chemistry->getTitle(); $maths->getTitle(); $physics->getPrice(); $chemistry->getPrice(); $maths->getPrice();
這將產生以下結果:
Physics for High School Advanced Chemistry Algebra 10 15 7
建構函式
建構函式是特殊型別的函式,每當建立物件時都會自動呼叫。因此,我們可以充分利用這種行為,透過建構函式初始化許多東西。
PHP 提供了一個名為__construct()的特殊函式來定義建構函式。您可以將任意數量的引數傳遞到建構函式中。
以下示例將為 Books 類建立一個建構函式,它將在物件建立時初始化書籍的價格和標題。
function __construct( $par1, $par2 ) { $this->title = $par1; $this->price = $par2; }
現在,我們不需要單獨呼叫 set 函式來設定價格和標題。我們只可以在建立物件時初始化這兩個成員變數。請檢視下面的示例:
$physics = new Books( "Physics for High School", 10 ); $maths = new Books ( "Advanced Chemistry", 15 ); $chemistry = new Books ("Algebra", 7 ); /* Get those set values */ $physics->getTitle(); $chemistry->getTitle(); $maths->getTitle(); $physics->getPrice(); $chemistry->getPrice(); $maths->getPrice();
這將產生以下結果:
Physics for High School Advanced Chemistry Algebra 10 15 7
解構函式
像建構函式一樣,您可以使用函式__destruct()定義解構函式。您可以在解構函式中釋放所有資源。
繼承
PHP 類定義可以透過使用 extends 子句從父類定義繼承。語法如下:
class Child extends Parent { <definition body> }
繼承的效果是子類(或子類或派生類)具有以下特徵:
自動擁有父類所有成員變數宣告。
自動擁有與父類相同的成員函式,這些函式(預設情況下)將以與父類中相同的方式工作。
以下示例繼承 Books 類並根據需求新增更多功能。
class Novel extends Books { var $publisher; function setPublisher($par){ $this->publisher = $par; } function getPublisher(){ echo $this->publisher. "<br />"; } }
現在,除了繼承的函式外,Novel 類還保留了兩個額外的成員函式。
函式重寫
子類中的函式定義會覆蓋父類中同名函式的定義。在子類中,我們可以修改從父類繼承的函式的定義。
在下面的例子中,getPrice 和 getTitle 函式被重寫以返回一些值。
function getPrice() { echo $this->price . "<br/>"; return $this->price; } function getTitle(){ echo $this->title . "<br/>"; return $this->title; }
公有成員
除非你另行指定,否則類的屬性和方法都是公有的。也就是說,它們可以在三種情況下被訪問:
從宣告它的類的外部
從宣告它的類的內部
從實現宣告它的類的另一個類中
到目前為止,我們看到的都是公有成員。如果你希望限制類成員的可訪問性,那麼你可以將類成員定義為私有或受保護。
私有成員
透過將成員指定為私有,你可以將其可訪問性限制在宣告它的類中。私有成員不能被繼承宣告它的類的類引用,也不能從類外部訪問。
可以使用private關鍵字放在成員前面,將類成員設為私有。
class MyClass { private $car = "skoda"; $driver = "SRK"; function __construct($par) { // Statements here run every time // an instance of the class // is created. } function myPublicFunction() { return("I'm visible!"); } private function myPrivateFunction() { return("I'm not visible outside!"); } }
當MyClass類被另一個類使用extends繼承時,myPublicFunction()將可見,$driver也可見。擴充套件類將無法感知或訪問myPrivateFunction和$car,因為它們被宣告為私有的。
受保護成員
受保護的屬性或方法可以在宣告它的類中訪問,以及在擴充套件該類的類中訪問。受保護的成員在上述兩種類之外是不可用的。可以使用protected關鍵字放在成員前面,將類成員設為受保護的。
以下是MyClass的不同版本:
class MyClass { protected $car = "skoda"; $driver = "SRK"; function __construct($par) { // Statements here run every time // an instance of the class // is created. } function myPublicFunction() { return("I'm visible!"); } protected function myPrivateFunction() { return("I'm visible in child class!"); } }
介面
介面被定義為為實現者提供通用的函式名稱。不同的實現者可以根據自己的需求實現這些介面。你可以說,介面是開發人員實現的骨架。
從PHP5開始,可以像這樣定義一個介面:
interface Mail { public function sendMail(); }
然後,如果另一個類實現了該介面,像這樣:
class Report implements Mail { // sendMail() Definition goes here }
常量
常量有點像變數,因為它儲存了一個值,但實際上更像一個函式,因為常量是不可變的。一旦你聲明瞭一個常量,它就不會改變。
宣告一個常量很容易,就像在這個版本的MyClass中所做的那樣:
class MyClass { const requiredMargin = 1.7; function __construct($incomingValue) { // Statements here run every time // an instance of the class // is created. } }
在這個類中,requiredMargin是一個常量。它用關鍵字const宣告,在任何情況下都不能更改為除1.7以外的任何值。請注意,常量的名稱前面沒有$符號,變數名有。
抽象類
抽象類是指不能被例項化,只能被繼承的類。你可以用關鍵字abstract宣告一個抽象類,像這樣:
當繼承抽象類時,父類宣告中標記為抽象的所有方法都必須由子類定義;此外,這些方法必須使用相同的作用域定義。
abstract class MyAbstractClass { abstract function myAbstractFunction() { } }
請注意,抽象類中的函式定義也必須以關鍵字abstract開頭。在非抽象類中,不允許有抽象函式定義。
Static關鍵字
將類成員或方法宣告為靜態,使其無需例項化類即可訪問。宣告為靜態的成員不能使用例項化的類物件訪問(儘管可以使用靜態方法)。
嘗試以下示例:
<?php class Foo { public static $my_static = 'foo'; public function staticValue() { return self::$my_static; } } print Foo::$my_static . "\n"; $foo = new Foo(); print $foo->staticValue() . "\n"; ?>
Final關鍵字
PHP 5 引入了 final 關鍵字,它透過在定義前面加上 final 來阻止子類覆蓋方法。如果類本身被定義為 final,則不能擴充套件它。
以下示例會導致致命錯誤:無法覆蓋最終方法 BaseClass::moreTesting()
<?php class BaseClass { public function test() { echo "BaseClass::test() called<br>"; } final public function moreTesting() { echo "BaseClass::moreTesting() called<br>"; } } class ChildClass extends BaseClass { public function moreTesting() { echo "ChildClass::moreTesting() called<br>"; } } ?>
呼叫父建構函式
與其為子類編寫一個全新的建構函式,不如透過顯式呼叫父建構函式,然後執行子類例項化所需的任何其他操作來編寫它。這是一個簡單的例子:
class Name { var $_firstName; var $_lastName; function Name($first_name, $last_name) { $this->_firstName = $first_name; $this->_lastName = $last_name; } function toString() { return($this->_lastName .", " .$this->_firstName); } } class NameSub1 extends Name { var $_middleInitial; function NameSub1($first_name, $middle_initial, $last_name) { Name::Name($first_name, $last_name); $this->_middleInitial = $middle_initial; } function toString() { return(Name::toString() . " " . $this->_middleInitial); } }
在這個例子中,我們有一個父類(Name),它有一個帶兩個引數的建構函式,還有一個子類(NameSub1),它有一個帶三個引數的建構函式。NameSub1 的建構函式透過使用 :: 語法顯式呼叫其父建構函式(傳遞其兩個引數)然後設定一個額外的欄位來工作。類似地,NameSub1 根據其覆蓋的父函式定義其非建構函式 toString() 函式。
注意 - 建構函式可以用與類名相同的名稱定義。在上面的例子中定義了它。