PHP 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 OOP 面向對象的特性