# 第十八章 面向對象的特性
學習要點:
1.OOP 的封裝
2.OOP 的繼承
3.OOP 的多態
面向對象的三個主要特性是封裝、繼承和多態。
**一.OOP的封裝**
隱藏對象的字段和實現細節,僅對外公開接口,控制在程序中字段的讀和修改的訪問級
別;將抽象得到的數據和行為(或功能)相結合,形成一個有機的整體,也就是將數據與
操作數據的源代碼進行有機的結合,形成“類”,其中數據和函數都是類的成員。
**字段的作用域**
1.public 公共的(類外可以訪問)
2.private 私有的(類內可以訪問)
3.protected 受保護的(類內和子類可以訪問,類外不可訪問)
創建使用了私有的字段,這樣外部就無法訪問了
```
class Computer { //類的字段(成員)
private $_name = '聯想120'; private $_model = 'LX';
}
```
通過一個公共方法作為入口,訪問私有字段,而必須使用$this關鍵字。
```
class Computer { //類的字段(成員)
private $_name = '聯想120'; private $_model = 'LX'; //通過公共方法來訪問私有字段
function run() { echo $this->_name;
}
} $computer->run ();
```
**屬性操作(私有字段的賦值與取值)**
可以設計兩個公共方法,一個方法為setName(),用于賦值;一個方法為getName(),
用于取值。
```
class Computer { //類的字段(成員)
private $_name; private $_model; //賦值
function setName($_name) { $this->_name = $_name;
} //取值
function getName() { return $this->_name;
}
} $computer = new Computer (); $computer->setName ( 'IBM' ); echo $computer->getName ();
```
如果有十個字段那么就必須要二十個方法才能夠賦值和取值,那么有沒有更簡便的方法
呢?PHP內置兩個方法(攔截器)專門用于取值與賦值:__set(),__get()。
```
class Computer { //類的字段(成員)
private $_name; private $_model; //所有字段的賦值都在這里進行
function __set($_key, $_value) { $this->$_key = $_value;
} //所有字段的取值都在這里進行
function __get($_key) { return $this->$_key;
}
} $computer = new Computer (); $computer->_model = 'LX'; echo $computer->_model;
```
方法私有:有些使用類里面的方法并不需要對外公開,只是里面運作的一部分,這個時
候可以將方法也封裝起來。
```
class Computer { //類的字段(成員)
private $_name; private $_model; //私有方法
private function getEcho() { echo '我是私有化的方法';
} //公共方法一般是對外的入口
public function run() { $this->getEcho ();
}
} $computer = new Computer (); $computer->run ();
```
建議:方法前面如果沒有修飾符,那么就是外部可訪問的公共方法,但為了讓程序更加
的清晰,建議在前面加上public。
**常量(constant)**
在類中可以定義常量,用來表示不會改變的值。對于從該類實例化的任何對象來說,常
量值在這些對象的整個生命周期中都保持不變。
```
class Computer { const PI = 3.1415926;
} echo Computer::PI;
```
**靜態類成員**
有時候,可能需要創建供所有類實例共享的字段和方法,這些字段和方法與所有的類實
例有關,但不能由任何特定對象調用。
```
class Computer { public static $_count = 0;
} echo Computer::$_count;
```
一般來說,必須將字段做成私有化。所以可能需要這么做:
```
class Computer { private static $_count = 0; public static function setRun() {
self::$_count ++;
} public static function getRun() { return self::$_count;
}
}
Computer::setRun (); echo Computer::getRun ();
```
**Instanceof關鍵字**
PHP5有一個instanceof關鍵字,使用這個關鍵字可以確定一個對象是類的實例、類的
子類,還是實現了某個特定接口,并進行相應的操作。
```
class Computer {
} $computer = new Computer (); echo ($computer instanceof Computer);
```
**二.OOP繼承**
繼承是從一個基類得到一個或多個類的機制。
繼承自另一個類的類被稱為該類的子類。這種關系通常用父類和孩子來比喻。子類將繼
承父類的特性。這些特性由屬性和方法組成。子類可以增加父類之外的新功能,因此子類也
被稱為父類的“擴展”。
在PHP中,類繼承通過extends關鍵字實現。繼承自其他類的類成為子類或派生類,子
類所繼承的類成為父類或基類。(PHP只支持單繼承,PHP不支持方法重載)。
```
class Computer { private $_name = '聯想120'; private function __get($_key) { return $this->$_key;
} public function run() { echo '我是父類';
}
} class NoteBookComputer extends Computer {
} $notebookcomputer = new NoteBookComputer (); $notebookcomputer->run (); echo $notebookcomputer->_name;
```
**字段和方法的重寫(覆蓋)**
有些時候,并不是特別需要父類的字段和方法,那么可以通過子類的重寫來修改父類的
字段和方法。
```
class Computer { public $_name = '聯想120'; protected function run() { echo '我是父類';
}
} class NoteBookComputer extends Computer { public $_name = 'IBM'; public function run() { echo '我是子類';
}
}
```
**子類調用父類的字段或方法**
為了安全,我們一般將父類的方法封裝了起來,這樣,外部就無法調用,只能被繼承它
的子類所看到。這個時候,就需要通過子類操作來調用父類了。
```
class Computer { protected $_name = '聯想120'; protected function run() { echo '我是父類';
}
} class NoteBookComputer extends Computer { public function getName() { echo $this->_name;
} public function getRun() { echo $this->run ();
}
}
```
**通過重寫調用父類的方法**
有的時候,我們需要通過重寫的方法里能夠調用父類的方法內容,這個時候就必須使用
語法:父類名::方法() 或者parent::方法()即可調用。
```
class Computer { protected function run() { echo '我是父類';
}
} class NoteBookComputer extends Computer { public function run() { echo Computer::run ();
}
}
```
final關鍵字可以防止類被繼承,有些時候只想做個獨立的類,不想被其他類繼承使用,
那么就必須使用這個關鍵字。建議只要是單獨的類,都加上這個關鍵字。
```
final class Computer { //無法繼承的類
final public function run() {
} //無法被繼承的方法
} class NoteBookComputer extends Computer { //會報錯
}
```
**抽象類和方法(abstract)**
抽象方法很特殊,只在父類中聲明,但在子類中實現。只有聲明為abstract的類可以聲
明抽象方法。
規則:
1.抽象類不能被實例化,只能被繼承。
2.抽象方法必須被子類方法重寫。
```
abstract class Computer { abstract function run();
} final class NotebookComputer extends Computer { public function run() { echo '我實現了';
}
}
```
**接口(interface)**
接口定義了實現某種服務的一般規范,聲明了所需的函數和常量,但不指定如何實現。
之所以不給出實現的細節,是因為不同的實體可能需要用不同的方式來實現公共的方法定
義。關鍵是要建立必須實現的一組一般原則,只要滿足了這些原則才能說實現了這個接口。
規則:
1.類全部為抽象方法(不需要聲明abstract)
2.接口抽象方法必須是public
3.成員(字段)必須是常量
```
interface Computer { const NAME = '聯想120'; public function run();
} final class NotebookComputer implements Computer { public function run() { echo '實現了接口的方法';
}
} $notebookcomputer = new NoteBookComputer (); $notebookcomputer->run (); echo Computer::NAME;
```
子類可以實現多個接口
```
interface Computer { const NAME = '聯想120'; public function run();
} interface Notebook { public function book();
} final class NotebookComputer implements Computer, Notebook { public function run() { echo '實現了接口的方法';
} public function book() { echo '實現了接口的方法';
}
}
```
**三.多態**
多態是指OOP 能夠根據使用類的上下文來重新定義或改變類的性質或行為,或者說接
口的多種不同的實現方式即為多態。把不同的子類對象都當作父類來看,可以屏蔽不同子類
對象之間的差異,寫出通用的代碼,做出通用的編程,以適應需求的不斷變化。
```
interface Computer { public function version(); public function work();
} class NotebookComputer implements Computer { public function version() { echo '聯想120';
} public function work() { echo '筆記本正在隨時攜帶運行!';
}
} class desktopComputer implements Computer { public function version() { echo 'IBM';
} public function work() { echo '臺式電腦正在工作站運行!';
}
} class Person { public function run($type) { $type->version (); $type->work ();
}
} $person = new Person (); $desktopcomputer = new desktopComputer (); $notebookcomputer = new NoteBookComputer (); $person->run ( $notebookcomputer );
```
?**注:文章出自李炎恢PHP視頻教程,本文僅限交流使用,不得用于商業用途,否則后果自負。**
- 介紹
- HTML/CSS 教程
- 第 1 章 HTML5 概述
- 第 2 章 基本格式
- 第 3 章 文本元素
- 第 4 章 超鏈接和路徑
- 第 5 章 分組元素
- 第 6 章 表格元素
- 第 7 章 文檔元素
- 第 8 章 嵌入元素
- 第 9 章 音頻和視頻
- 第 10 章 表單元素[上]
- 第 10 章 表單元素[中]
- 第 10 章 表單元素[下]
- 第 11 章 全局屬性和其他
- 第 12 章 CSS 入門
- 第 13 章 CSS 選擇器[上]
- 第 14 章 CSS 顏色與度量單位
- 第 15 章 CSS 文本樣式[上]
- 第 15 章 CSS 文本樣式[下]
- 第 16 章 CSS 盒模型[上]
- 第 16 章 CSS 盒模型[下]
- 第 17 章 CSS 邊框與背景[上]
- 第 17 章 CSS 邊框與背景[下]
- 第 18 章 CSS 表格與列表
- 第 19 章 CSS 其他樣式
- 第 20 章 CSS3 前綴和 rem
- 第 21 章 CSS3 文本效果
- 第 21 章 CSS3 文本效果
- 第 23 章 CSS3 邊框圖片效果
- 第 24 章 CSS3 變形效果[下]
- 第 25 章 CSS3 過渡效果
- 第 26 章 CSS3 動畫效果
- 第 27 章 CSS 傳統布局[上]
- 第 27 章 CSS 傳統布局[下]
- 第 28 章 CSS3 多列布局
- 第 29 章 CSS3 彈性伸縮布局[上]
- 第 29 章 CSS3 彈性伸縮布局[中]
- 第 29 章 CSS3 彈性伸縮布局[下]
- 第 30 章 使用 Emmet 插件
- Bootstrap 教程
- 第 1 章 Bootstrap 介紹
- 第 2 章 排版樣式
- 第 3 章 表格和按鈕
- 第 4 章 表單和圖片
- 第 5 章 柵格系統
- 第 6 章 輔組類和響應式工具
- 第 7 章 圖標菜單按鈕組件
- 第 8 章 輸入框和導航組件
- 第 9 章 路徑分頁標簽和徽章組件
- 第 10 章 巨幕頁頭縮略圖和警告框組件
- 第 11 章 進度條媒體對象和 Well 組件
- 第 12 章 列表組面板和嵌入組件
- 第 13 章 模態框插件
- 第 14 章 下拉菜單和滾動監聽插件
- 第 15 章 標簽頁和工具提示插件
- 第 16 章 彈出框和警告框插件
- 第 17 章 按鈕和折疊插件
- 第 18 章 輪播插件
- 第 19 章 附加導航插件
- 第 20 章 項目實戰--響應式導航[1]
- 第 20 章 項目實戰--響應式輪播圖[2]
- 第 20 章 項目實戰--首頁內容介紹[上][3]
- 第 20 章 項目實戰--首頁內容介紹[下][4]
- 第 20 章 項目實戰--資訊內容[5,6]
- 第 20 章 項目實戰--案例和關于[7]
- javaScript 教程
- javascript快速入門1--JavaScript前世今生,HelloWorld與開發環境
- javascript快速入門2--變量,小學生數學與簡單的交互
- javascript快速入門3--分支判斷與循環
- javascript快速入門4--函數與內置對象
- javascript快速入門5--數組與對象
- javascript快速入門6--Script標簽與訪問HTML頁面
- javascript快速入門7--ECMAScript語法基礎
- javascript快速入門8--值,類型與類型轉換
- javascript快速入門9--引用類型
- javascript快速入門10--運算符,語句
- javascript快速入門11--正則表達式
- javascript快速入門12--函數式與面向對象
- javascript快速入門13--BOM——瀏覽器對象模型(Browser Object Model)
- javascript快速入門14--DOM基礎
- javascript快速入門15--節點
- javascript快速入門15--表單
- javascript快速入門16--表格
- javascript快速入門17--事件
- javascript快速入門18--樣式
- javascript快速入門19--定位
- javascript快速入門20--Cookie
- javascript快速入門21--DOM總結
- javascript快速入門22--Ajax簡介
- javascript快速入門23--XHR—XMLHttpRequest對象
- javascript快速入門24--XML基礎
- javascript快速入門25--瀏覽器中的XML
- javascript快速入門26--XPath
- javascript快速入門27--XSLT基礎
- PHP 教程
- 第一章 如何加載運行已發布的PHP項目
- 第二章 PHP基礎
- 第三章 操作符與控制結構
- 第四章 數學運算
- 第五章 數組
- 第六章 目錄與文件
- 第七章 自定義函數
- 第八章 字符串處理
- 第九章 正則表達式
- 第十章 日期與時間
- 第十一章 表單與驗證
- 第十二章 會話控制
- 第十三章 上傳文件
- 第十四章 處理圖像
- 第十五章 MySQL 數據庫
- 第十六章 PHP 操作MySQL
- 第十七章 面向對象基礎
- 第十八章 面向對象的特性
- 第十九章 面向對象的工具