[TOC]
## 單態(單例、單件)設計模式
單態模式的主要作用是保證在面向對象編程設計中,一個類只能有一個實例對象存在。
```
<?php
class DB {
private static $obj = null; //聲明一個私有的,靜態的成員屬性$obj
private function __construct() { //私有構造方法,只能在類的內部實例化對象
echo "連接數據庫成功<br>";
}
public static function getInstance() { // 通過此靜態方法才能獲取本類的對象
if(is_null(self::$obj)) //如果本類中的$obj為空,說明還沒有被實例化過
self::$obj = new self(); //實例化本類對象
return self::$obj; //返回本類的對象
}
public function query($sql) { //執行SQL語句完成對數據庫的操作
echo $sql;
}
}
$db = DB::getInstance(); //只能使用靜態方法getInstance()去獲取DB類的對象
$db -> query("select * from user"); //訪問對象中的成員
```
```
<?php
/*
* 單態(單例, 單件)設計模式 -- 最適合PHP使用這個設計模式
* 1. 如果想讓一個類, 只能有一個對象, 就要先讓這個類, 不能創建對象 , 將構造方法 private
* 2. 可以在類的內存使用一個表態方法,來創建對象
*/
class Person {
static $obj = null;
private function __construct() {
}
static function getObj() {
//如果第一次調用時, 沒有對象則創建, 以后調用時, 直接使用第一次創建的對象
if(is_null(self::$obj))
self::$obj = new self;
return self::$obj;
}
function __destruct() {
echo "################<br>";
}
function say() {
echo "aaaaaaaaaaaaaaaaa<br>";
}
}
$p = Person::getObj();
$p = Person::getObj();
$p = Person::getObj();
$p = Person::getObj();
$p = Person::getObj();
$p = Person::getObj();
$p = Person::getObj();
$p -> say();
```
## PHP抽象方法和抽象類
在OOP語言中,一個類可以有一個或多個子類,而每個類都有至少一個公有方法做為外部代碼訪問其的接口。而抽象方法就是為了方便繼承而引入的。
當類中有一個方法,他沒有方法體,也就是沒有花括號,直接分號結束,象這種方法我們叫抽象方法,必須使用關鍵字abstract定義。
如: public abstract function fun();
包含這種方法的類必須是抽象類也要使用關鍵字abstract加以聲明。(即使用關鍵字abstract 修飾的類為抽象類)
抽象類的特點:
不能實例化,也就是不能new成對象
**若想使用抽象類,就必須定義一個類去繼承這個抽象類,并定義覆蓋父類的抽象方法(實現抽象方法)。**
**其實抽象類對于子類(實現類),有一個約束的作用**,
含有抽象方法的類肯定是抽象類,但是不是所有的抽象類都必須包含抽象方法。
```
<?php
/*
* 1. 什么是抽象方法 ?
* 定義: 一個方法如果沒有方法體(一個方法,不使用"{}", 直接使用分號結束的方法,才是沒有方法體的方法 ),則這個方法就是抽象方法
* 一、 聲明一個方法,不使用{},而直接分號結束
* 二、如果是抽象方法,必須使用 abstract(抽象關鍵字來修飾)
* 2. 什么是抽象類 ?
* 一、 如果一個類中有一個方法是抽象的方法, 則這個類就是抽象類
* 二、如果聲明一個抽象類, 則這個類必須要使用 abstract關鍵字來修飾
* 注意:
* 1. 只要使用 abstract修飾的類, 就是抽象類
* 2. 抽象類是一種特殊的類, 特殊在哪里(在抽象類中可以有抽象方法)
* 3. 除了在抽象類中可以有抽象方法,以外,和正常的類完全一樣
* 注意2:
* 1. 抽象類不能實例化對象(不能創建出對象)
* 2. 如果看見抽象類, 就必須寫這個類的子類, 將抽象類中的抽象方法覆蓋(加上方法體)
* 3. 子類必須全部實現(覆蓋重寫)抽象方法, 這個子類才能創建對象, 如果只實現部分, 那么還有抽象方法,則類也就必須是抽象類
* 抽象方法作用:
* 抽象方法的作用就是規定了,子類必須有這個方法的實現, 功能交給子類
* 只寫出來結構, 而沒有實現, 實現交給具體的子類(按自己的功能)去實現
* 抽象類的作用:
* 就是要求子類的結構, 所以抽象類就是一個規范
*/
abstract class Person {
public $name;
public $age;
//特殊的方法抽象方法的存在
abstract function say();
abstract function eat();
function run() {
echo "11111111111111<br>";
}
function sleep() {
echo "2222222222222222<br>";
}
}
class StudentCn extends Person {
function say() {
echo "我是中國人,我說中文<br>";
}
function eat() {
echo "我是中國人,我用筷子吃飯";
}
}
class StudentEn extends Person {
function say() {
echo "I am English ,i say english<br>";
}
function eat() {
echo "我是外國人, 我用刀子和叉子吃飯";
}
}
$s1 = new StudentEn();
$s1 -> say();
$s1 -> eat();
```
## PHP面向對象接口技術
PHP與大多數面向對象編程語言一樣,不支持多重繼承,也就是說每個類只能繼承一個父類。為了解決這個這個問題,PHP引入了接口,接口的思想是指定了一個實現了該接口的類必須實現的一系列函數。
> 抽象類與接口的區別
**定義**
1. 抽象類表示該類中可能已經有一些方法的具體定義。
1. 接口就僅僅只能定義各個方法的界面,不能有具體的實現代碼在成員方法中。
**用法**
1. 抽象類是子類用來繼承的,當父類已有實際功能的方法時,該方法在子類中可以不必實現。
2. 實現一個接口,必須實現接口中所有定義的方法,不能遺漏任何一個。
```
<?php
/* 抽象類是一種抽象的類, 接口是一種特殊的抽象類, 接口也是一種特殊特殊的類
* 1. 抽象類和接口中都有抽象方法
* 2. 抽象類和接口都不能創建實例對象
* 3. 抽象類和接口的使用意義也就是作用相同
*
* 接口和抽象類相比, 特殊在哪里?
* 1. 接口中的方法,必須全要是抽象方法(不能用不抽象的方法)
* 所以在接口中的抽象方法不需要使用abstract, 直接使用分號結束即可
* 2. 接口中的成員屬性, 必須是常量(不能有變量)
* 3. 所有的權限必須是公有的(public)
* 4. 聲明接口不使用class, 而是使用interface
*
* 接口應用的一些細節:
* 1. 可以使用extends 讓一個接口繼承另一接口 (接口和接口---- 只有擴展新抽象方法, 沒有覆蓋的關系)
* 2. 可以使用一個類來實現接口中的全部方法, 也可以使用一個抽象類, 來實現接口中的部分方法
* (類與接口, 抽象類與接口 -- 覆蓋 -- 重寫, 實現接口中的抽象方法)
* 3. 就不要使用extends這個關鍵字, 使用implements實現 implements 相當于 extends
* extends 繼承(擴展), 這個在PHP中, 一個類只能有一個父類
* 4. 一個類可以在繼承另一個類的同時, 使用implements實現一個接口, 可以實現個接口(一定要先繼承, 再實現接口)
* 5. 實現多個接口, 只需要使用逗號分開多個接口即可
*/
//聲明一個接口使用interface
interface Demo {
const NAME="妹子";
const AGE = 20;
public function test();
public function test2();
function test3();
}
interface Test extends Demo {
function test4();
}
class World {
function test5() {
}
}
interface Abc {
function test6();
}
class Hello extends World implements Test,Abc {
function test() {
}
function test2() {
echo "22222222222222";
}
function test3() {
}
function test4() {
}
function test6() {
}
}
$h = new Hello;
$h->test2();
```
## PHP多態的應用
面向對象的特性多態
對象的多態性是指在父類中定義的屬性或行為被子類繼承之后,可以具有不同的數據類型或表現出不同的行為。這使得同一個屬性或行為在父類及其各個子類中具有不同的語義。
例如:"幾何圖形"的"繪圖"方法,"橢圓"和"多邊形"都是"幾何圖"的子類,其"繪圖"方法功能不同。
```
<?php
/* 多態特性
* 1. 程序擴展準備
* 技術:
* 1. 必須有繼承關系, 父類最好是接口或抽象類
*/
interface USB {
const WIDTH = 12;
const HEIGHT = 3;
function load();
function run();
function stop();
}
class Cumputer {
function useUSB(USB $usb) {
$usb -> load();
$usb -> run();
$usb -> stop();
}
}
class Mouse implements USB{
function load() {
echo "加載鼠標成功!<br>";
}
function run() {
echo "運行鼠標功能!<br>";
}
function stop() {
echo "鼠標工作結束!<br>";
}
}
class KeyPress implements USB {
function load() {
echo "加載鍵盤成功!<br>";
}
function run() {
echo "運行鍵盤成功!<br>";
}
function stop() {
echo "停止鍵盤使用!<br>";
}
}
class Worker {
function work() {
$c = new Cumputer();
$m = new Mouse;
$k = new KeyPress;
$c->useUSB($k);
$c->useUSB($m);
}
}
$w = new Worker;
$w -> work();
```