(一):面向?qū)ο缶幊蘋OP
OOP(Object-Oriented Programming), 面向?qū)ο蟮木幊?技術(shù)為編程人員敞開了一扇大門瘟判,使其編程的代碼更簡(jiǎn)潔、更易于維護(hù)宣蔚,并且具有更強(qiáng)的可重用性
(二):OOP軟件的三個(gè)目標(biāo)
重用性 拓展性 靈活性
(三):面向?qū)ο缶幊痰娜筇匦?/h3>
封裝:面向?qū)ο蟮能浖闹匾獌?yōu)點(diǎn)是封裝也叫 ”數(shù)據(jù)隱藏” 封裝就是把對(duì)象中的成員屬性和成員方法加上修飾符,使其盡可能隱藏對(duì)象的內(nèi)部細(xì)節(jié),以達(dá)到對(duì)成員的訪問控制
繼承:繼承允許子類與類之間創(chuàng)建層次關(guān)系潜支,子類將從它的超類(父類)中繼承屬性和方法,通過繼承可以在原有類的基礎(chǔ)上創(chuàng)建出新的類奔则,由一個(gè)類衍生出更復(fù)雜更專門的類技即,使代碼具有更好的重用性,這對(duì)于功能的設(shè)計(jì)和抽象很有用绳瘟,使其升級(jí)和維護(hù)更加的靈活雕憔。
多態(tài):面向?qū)ο蟮恼Z(yǔ)言必須支持多態(tài)
- 父類被子類繼承之后 擁有不同的數(shù)據(jù)類型和行為表現(xiàn)
- 一個(gè)接口可以有多種不同的實(shí)現(xiàn) ,對(duì)應(yīng)不同的數(shù)據(jù)類型和行為表現(xiàn)
- 一個(gè)類可以被實(shí)例化多個(gè)對(duì)象糖声,不同對(duì)象也有不同的數(shù)據(jù)類型和表現(xiàn)行為
(四):類和對(duì)象的概念
類: 類是對(duì)具有相同或者相似特征事物抽象出的描述斤彼,其中靜態(tài)的特征稱為“屬性”分瘦,動(dòng)態(tài)的行為稱為“方法”。
- 類名使用class關(guān)鍵字定義琉苇,類名遵從標(biāo)識(shí)符統(tǒng)一規(guī)范
- 類中成員只能包含屬性嘲玫、方法和常量,不能有其他語(yǔ)句塊
- 成員屬性必須加上修飾符并扇,成員方法可以不加趁冈,默認(rèn)為public
- 成員屬性可以初始化值 但只能是固定類型值 不能含有運(yùn)算符或變量
- 當(dāng)一個(gè)方法在類定義內(nèi)部被調(diào)用時(shí),有一個(gè)可用的偽變量
$this
拜马。 $this
是一個(gè)對(duì)象的引用
對(duì)象:面向?qū)ο蟮能浖猩保瑢?duì)象幾乎可以表示所有的實(shí)物對(duì)象和概念對(duì)象,可以表示物理實(shí)際存在的對(duì)象:一個(gè)人俩莽,一棵樹等旺坠。也可以表示軟件中才有的概念對(duì)象:一個(gè)文件,一個(gè)資源等扮超。
類和對(duì)象的關(guān)系:
- 類是對(duì)象的抽象描述取刃,沒有類就不可能有對(duì)象,每一個(gè)對(duì)象必須隸屬于某個(gè)類出刷。
- 對(duì)象是類的具體體現(xiàn)璧疗,沒有具體對(duì)象的類,毫無意義就是一堆死代碼馁龟,想發(fā)揮一個(gè)類的作用崩侠,就必須讓這個(gè)類有對(duì)象。
(五):訪問控制
對(duì)屬性或方法的訪問控制坷檩,是通過在前面添加關(guān)鍵字 public(公有)却音,protected(受保護(hù))或 private(私有)來實(shí)現(xiàn)的。
封裝:面向?qū)ο蟮能浖闹匾獌?yōu)點(diǎn)是封裝也叫 ”數(shù)據(jù)隱藏” 封裝就是把對(duì)象中的成員屬性和成員方法加上修飾符,使其盡可能隱藏對(duì)象的內(nèi)部細(xì)節(jié),以達(dá)到對(duì)成員的訪問控制
繼承:繼承允許子類與類之間創(chuàng)建層次關(guān)系潜支,子類將從它的超類(父類)中繼承屬性和方法,通過繼承可以在原有類的基礎(chǔ)上創(chuàng)建出新的類奔则,由一個(gè)類衍生出更復(fù)雜更專門的類技即,使代碼具有更好的重用性,這對(duì)于功能的設(shè)計(jì)和抽象很有用绳瘟,使其升級(jí)和維護(hù)更加的靈活雕憔。
多態(tài):面向?qū)ο蟮恼Z(yǔ)言必須支持多態(tài)
- 父類被子類繼承之后 擁有不同的數(shù)據(jù)類型和行為表現(xiàn)
- 一個(gè)接口可以有多種不同的實(shí)現(xiàn) ,對(duì)應(yīng)不同的數(shù)據(jù)類型和行為表現(xiàn)
- 一個(gè)類可以被實(shí)例化多個(gè)對(duì)象糖声,不同對(duì)象也有不同的數(shù)據(jù)類型和表現(xiàn)行為
類: 類是對(duì)具有相同或者相似特征事物抽象出的描述斤彼,其中靜態(tài)的特征稱為“屬性”分瘦,動(dòng)態(tài)的行為稱為“方法”。
- 類名使用class關(guān)鍵字定義琉苇,類名遵從標(biāo)識(shí)符統(tǒng)一規(guī)范
- 類中成員只能包含屬性嘲玫、方法和常量,不能有其他語(yǔ)句塊
- 成員屬性必須加上修飾符并扇,成員方法可以不加趁冈,默認(rèn)為public
- 成員屬性可以初始化值 但只能是固定類型值 不能含有運(yùn)算符或變量
- 當(dāng)一個(gè)方法在類定義內(nèi)部被調(diào)用時(shí),有一個(gè)可用的偽變量
$this
拜马。$this
是一個(gè)對(duì)象的引用
對(duì)象:面向?qū)ο蟮能浖猩保瑢?duì)象幾乎可以表示所有的實(shí)物對(duì)象和概念對(duì)象,可以表示物理實(shí)際存在的對(duì)象:一個(gè)人俩莽,一棵樹等旺坠。也可以表示軟件中才有的概念對(duì)象:一個(gè)文件,一個(gè)資源等扮超。
類和對(duì)象的關(guān)系:
- 類是對(duì)象的抽象描述取刃,沒有類就不可能有對(duì)象,每一個(gè)對(duì)象必須隸屬于某個(gè)類出刷。
- 對(duì)象是類的具體體現(xiàn)璧疗,沒有具體對(duì)象的類,毫無意義就是一堆死代碼馁龟,想發(fā)揮一個(gè)類的作用崩侠,就必須讓這個(gè)類有對(duì)象。
對(duì)屬性或方法的訪問控制坷檩,是通過在前面添加關(guān)鍵字 public(公有)却音,protected(受保護(hù))或 private(私有)來實(shí)現(xiàn)的。
? | 本類 | 子類 | 外部 |
---|---|---|---|
public | 可以訪問 | 可以訪問 | 可以訪問 |
protected | 可以訪問 | 可以訪問 | 不可以訪問 |
private | 可以訪問 | 不可以訪問 | 不可以訪問 |
(六):繼承的實(shí)現(xiàn)
1.一個(gè)類可以通過繼承擁有另一個(gè)類的屬性和方法矢炼,其中被繼承的類稱為基類系瓢、超類或父類,繼承的類稱為子類句灌。
2.PHP繼承是單向的夷陋,子類可以從父類或者超類繼承特性,父類不可以從子類獲取特性
3.子類就會(huì)繼承父類所有公有的和受保護(hù)的方法胰锌。除非子類覆蓋了父類的方法骗绕,被繼承的方法都會(huì)保留其原有功能。
4.繼承對(duì)于功能的設(shè)計(jì)和抽象是非常有用的匕荸,而且對(duì)于類似的對(duì)象增加新功能就無須重新再寫這些公用的功能爹谭。
class Human{}
class blackMan extend Human{}
class whiteMan extend Huamn{}
class englishMan extend whiteMan{}
(七):靜態(tài)屬性
使用static修飾的成員為靜態(tài)成員枷邪,只隸屬類本身榛搔,可以看成是所有對(duì)象的 “公有數(shù)據(jù)” 诺凡。
1.靜態(tài)屬性使用類名訪問,在類中可以使用self代替類本身践惑,
類名::$靜態(tài)屬性名
注釋:雙冒號(hào)::是范圍解析操作符, 用于訪問靜態(tài)成員腹泌,類常量,還可以用于覆蓋類中的屬性和方法尔觉。
2.靜態(tài)方法中不能出現(xiàn)動(dòng)態(tài)內(nèi)容凉袱,即不能有$this
這樣的內(nèi)容。
注釋:由于靜態(tài)方法不需要通過對(duì)象即可調(diào)用侦铜,所以偽變量$this
在靜態(tài)方法中不可用
3.如果一個(gè)方法中不含有$this
則認(rèn)為這個(gè)方法是靜態(tài)方法专甩,按照嚴(yán)格語(yǔ)法最好在方法體上加上static修飾
4.用靜態(tài)方式調(diào)用一個(gè)非靜態(tài)方法會(huì)導(dǎo)致一個(gè) E_STRICT 級(jí)別的錯(cuò)誤
5.靜態(tài)屬性不可以由對(duì)象通過 -> 操作符來訪問。
靜態(tài)實(shí)例
//計(jì)算實(shí)例化對(duì)象的個(gè)數(shù)
class demo
{
public static $counter;
public function __construct()
{
echo "這是第".++self::$counter."個(gè)對(duì)象<br />";
}
}
new demo();
new demo();
//單列設(shè)計(jì)模式的基本寫法
class Single
{
//定義一個(gè)靜態(tài)屬性,用于存儲(chǔ)一個(gè)實(shí)例化的對(duì)象
private static $instance=null;
//私有化構(gòu)造方法
private function __construct()
{
//初始化代碼
}
//產(chǎn)生對(duì)象的方法
public static getObj()
{
if(!isset(self::$instance))
{
$obj = new self;
self::$instance = $obj;
return $obj;
}else{
return self::$instance;
}
}
//私有化魔術(shù)克隆方法
private function __clone()
{
//代碼
}
}
$obj1 = Single::getObj();
$obj2 = Single::getObj();
var_dump($obj1);
var_dump($obj2);
//工廠模式部分
class Human{};
class Animal{};
class factory
{
static function getObj($className)
{
$obj = new $className();
return $obj;
}
}
$obj1 = factory::getObj("Human");
$obj2 = factory::getObj("Animal");
(八):覆蓋override(也叫:重寫)
基本概念:在子類中從父類繼承下來的屬性或方法重新的“定義”钉稍,覆蓋掉原有的涤躲,等于將原有的方法和屬性重新寫了一次。
1.重寫的基本要求是方法的參數(shù)要保持一致贡未。
2.訪問權(quán)限不能比原有的兄钟!(public > protected > privte)
比如:父類中是:public 子類只能是:public;父類中是:protected 子類中可以是:public 和protected
3.私有屬性和私有方法不能覆蓋,子類中出現(xiàn)同名的方法和屬性俊卤,就當(dāng)是子類自己重新定義的嫩挤。但是方法的參數(shù)要保持一致。
4.構(gòu)造方法的重寫消恍,比較寬松岂昭,參數(shù)可以與父類不一致
class Human
{
public $id;
public $name;
public $sex;
private $age;
protected $addr;
public function __construct($id,$name,$sex,$age,$addr)
{
$this->id = $id;
$this->name = $name;
$this->sex = $sex;
$this->age = $age;
$this->addr = $addr;
}
}
class pre extends Human
{
public $num;
public $nationality;
public $skin;
public function __construct($id,$name,$sex,$age,$addr,$num,$nationality,$skin)
{
parent::__construct($id,$name,$sex,$age,$addr);
$this->num = $num;
$this->nationality = $nationality;
$this->skin = $skin;
}
}
(九):重載overloading
PHP所提供的"重載"(overloading)是指動(dòng)態(tài)地"創(chuàng)建"類屬性和方法。我們是通過魔術(shù)方法(magic methods)來實(shí)現(xiàn)的狠怨。
屬性重載:
public void __set ( string $name , mixed $value )
public mixed __get ( string $name )
public bool __isset ( string $name )
public void __unset ( string $name )
參數(shù) $name
是指要操作的變量名稱佩抹。__set()方法的 $value
參數(shù)指定了 $name
變量的值。
方法重載:
public mixed __call ( string $name , array $arguments )
public static mixed __callStatic ( string $name , array $arguments )
$name
參數(shù)是要調(diào)用的方法名稱取董。 $arguments
參數(shù)是一個(gè)枚舉數(shù)組棍苹,包含著要傳遞給方法 $name
的參數(shù)。
(十):final關(guān)鍵字
一個(gè)類既然能被繼承茵汰,但是也有類不希望被繼承枢里,方法能被重寫,但是也有方法不希望被重寫蹂午,所以需要使用關(guān)鍵字:final
PHP 5 新增了一個(gè) final 關(guān)鍵字栏豺。如果父類中的方法被聲明為 final,則子類無法覆蓋該方法豆胸。如果一個(gè)類被聲明為 final奥洼,則不能被繼承
(十一):對(duì)象復(fù)制
對(duì)象為引用類型,這里賦值類似于起別名晚胡,賦值產(chǎn)生的對(duì)象是復(fù)制的“引用關(guān)系灵奖,賦值產(chǎn)生的還是同一個(gè)對(duì)象
通過克隆可以產(chǎn)生一完全獨(dú)立的對(duì)象嚼沿,使用關(guān)鍵字:clone
僅僅使用clone關(guān)鍵字去克隆一個(gè)對(duì)象,只能克隆出他的非資源費(fèi)非對(duì)象數(shù)據(jù)瓷患,要完整克隆一個(gè)對(duì)象骡尽,需要使用__clone()魔術(shù)方法,在克隆時(shí)自動(dòng)觸發(fā)
//在外部克隆時(shí),自動(dòng)觸發(fā)
public function __clone()
{
$this-> handle = fopne("./readme.txt","r");
}
public function __destruct()
{
fclose($this->handle);
}
}
//實(shí)例一個(gè)對(duì)象
$person1 = new Human("岳飛","male");
//克隆出一個(gè)完全一樣的對(duì)象
$person2 = clone($person1);
(十二):對(duì)象信息保存
所有php里面的值都可以使用函數(shù) serialize() 來返回一個(gè)包含字節(jié)流的字符串來表示擅编。 unserialize() 函數(shù)能夠重新把字符串變回php原來的值攀细。 序列化一個(gè)對(duì)象將會(huì)保存對(duì)象的所有變量,但是不會(huì)保存對(duì)象的方法爱态,只會(huì)保存類的名字谭贪。
序列化:serialize() : 用來將對(duì)象轉(zhuǎn)化成字符串保存的函數(shù),將轉(zhuǎn)化后的字符串保存至文本或者數(shù)據(jù)庫(kù)中锦担,便于跨腳本使用
當(dāng)對(duì)一個(gè)對(duì)象進(jìn)行“序列化”操作的時(shí)候故河,會(huì)自動(dòng)調(diào)用類中的__sleep()方法
“__sleep()魔術(shù)方法中可以進(jìn)行一些數(shù)據(jù)(資源)的清理工作,并返回一個(gè)數(shù)組吆豹,該數(shù)組可以存儲(chǔ)一些想要進(jìn)行序列化的對(duì)象的屬性——即可以挑選屬性進(jìn)行序列化鱼的。”
//部分代碼
//序列化的時(shí)候,會(huì)自動(dòng)觸發(fā)魔術(shù)方法__sleep()
public function __sleep()
{
return array("name","sex","handle");
}
public function __destruct()
{
fclose($this->handle);
}
}
$person = new Human("喬峰","male");
$str = serialize($person);
file_put_contents("./readme.txt",$str);
反序列化:unserialize() : 將序列化后的字符串轉(zhuǎn)換回對(duì)象的格式
注釋:反序列化時(shí)痘煤,必須有對(duì)應(yīng)的類聲明
“__wakeup()魔術(shù)方法中凑阶,在進(jìn)行反序列化操作的時(shí)候進(jìn)行某些必備的“數(shù)據(jù)恢復(fù)工作”,比如:打開某個(gè)資源等”
//部分代碼
//在反序列化的時(shí)候自動(dòng)調(diào)用的魔術(shù)方法__wakeup();
public function __wakeup()
{
$this->handle=fopen("./readme.txt","r");
}
public function __destruct()
{
fclose($this->handle);
}
}
$str = file_get_contents("./readme.txt","r");
$obj = unserialize($str);
(十三):自動(dòng)加載__autoload()
__aotoload()是一個(gè)單獨(dú)的函數(shù)不是一個(gè)類方法衷快。
__autoload()的主要用途是嘗試包含或請(qǐng)求任何用來初始化所需要的類文件宙橱。
__autoload()會(huì)在實(shí)例化一個(gè)還沒有被聲明的類時(shí)自動(dòng)調(diào)用
//部分代碼片段
function __autoload($classname)
{
require "./libs/{$classname}.class.php";
}
$p = new Human("喬峰","male","35","song");
var_dump($p);
補(bǔ)充:spl_autoload_register()注冊(cè)給定的函數(shù)作為 __autoload 的實(shí)現(xiàn)【參看PHP手冊(cè)】
(十四):抽象類
可以定義不含方法體的方法,即為:抽象方法蘸拔,需要是使用abstract定義师郑,含有抽象方法的的類,一定是抽象類调窍,必須abstract聲明成抽象類
1.抽象方法必須只聲明調(diào)用方式宝冕,不能定義具體功能實(shí)現(xiàn)
2.抽象方法不能被設(shè)置為私有(不能被private修飾)
3.抽象方法不能有{},直接;結(jié)束
4.抽象類不能被實(shí)例化
5.繼承抽象類的子類邓萨,必須定義所有的抽象方法地梨,子類中定義的抽象方法訪問控制,不能比抽象類中定義的更嚴(yán)格
6.子類中必須完成繼承過來的抽象方法的具體實(shí)現(xiàn)缔恳,這就是抽象類的約束作用
7.抽象類的約束作用可以有效的做到項(xiàng)目開發(fā)中的規(guī)范性要求宝剖,實(shí)現(xiàn)項(xiàng)目管理。
//部分代碼
abstract class Human
{
public $name;
public $addr;
public function __construct($name,$addr)
{
$this->name = $name;
$this->addr = $addr;
}
//公有的抽象方法
public abstract function reading();
//受保護(hù)的抽象方法
protected abstract function runing();
}
class person extends HUmann
{
public function reading()
{
//抽象方法的實(shí)現(xiàn)
}
public function runing()
{
//抽象方法的實(shí)現(xiàn)
}
}
(十五):接口
如果在一個(gè)抽象類中只包含抽象方法時(shí)歉甚,我們把該"類"稱為接口(interface),它需要單獨(dú)的類去實(shí)現(xiàn)(implements)
基本規(guī)則:
- 接口的所有方法都是抽象方法万细,但是不需要使用abstract修飾
- 接口中定義的所有方法都必須是公有
- 要實(shí)現(xiàn)一個(gè)接口,必須使用implements操作符類中必須實(shí)現(xiàn)接口中定義的所有方法
- 一個(gè)類可以實(shí)現(xiàn)多個(gè)接口纸泄,實(shí)現(xiàn)多個(gè)接口時(shí)赖钞,接口中的方法名不能重復(fù)
- 接口與接口之間可以繼承腰素,使用extends
- 接口中也可以定義常量。接口常量和類常量的使用完全相同仁烹,但是不能被子類或子接口所覆蓋耸弄。
interface Boss
{
public function fun1();
public function fun2();
public function fun3();
}
interface Message
{
public function fun4();
public function fun5();
public function fun6();
}
abstract class Engineer implements Boss,Message
{
//實(shí)現(xiàn)抽象方法1
public function fun1()
{
}
//實(shí)現(xiàn)抽象方法2
public function fun2()
{
}
public function fun3();
public function fun4();
public function fun5();
//實(shí)現(xiàn)抽象方法6
public function fun6()
{
}
}
class Programmer extends Engineer
{
public function fun3(){};
public function fun4(){};
public function fun5(){};
}
(十六):常見的魔術(shù)方法
方法名 | 描述 |
---|---|
__construct() | 構(gòu)造函數(shù)的類會(huì)在每次創(chuàng)建新對(duì)象時(shí)先調(diào)用此方法咧虎,所以非常適合在使用對(duì)象之前做一些初始化工作 |
__destruct() | 析構(gòu)函數(shù)會(huì)在到某個(gè)對(duì)象的所有引用都被刪除或者當(dāng)對(duì)象被顯式銷毀時(shí)執(zhí)行 |
__set() | 在給不可訪問屬性賦值時(shí)卓缰,__set() 會(huì)被調(diào)用 |
__get() | 讀取不可訪問屬性的值時(shí),__get() 會(huì)被調(diào)用 |
__call() | 在對(duì)象中調(diào)用一個(gè)不可訪問方法時(shí)砰诵,__call() 會(huì)被調(diào)用 |
__callStatic() | 用靜態(tài)方式中調(diào)用一個(gè)不可訪問方法時(shí)征唬,__callStatic() 會(huì)被調(diào)用 |
__isset() | 當(dāng)對(duì)不可訪問屬性調(diào)用 isset() 或 empty() 時(shí),__isset()會(huì)被調(diào)用 |
__unset() | 當(dāng)對(duì)不可訪問屬性調(diào)用 unset() 時(shí)茁彭,__unset()會(huì)被調(diào)用 |
__sleep() | serialize() 函數(shù)會(huì)檢查類中是否存在一個(gè)魔術(shù)方法 __sleep()总寒。如果存在,該方法會(huì)先被調(diào)用理肺,然后才執(zhí)行序列化操作摄闸。此功能可以用于清理對(duì)象,并返回一個(gè)包含對(duì)象中所有應(yīng)被序列化的變量名稱的數(shù)組 |
__wakeup() | unserialize() 會(huì)檢查是否存在一個(gè) __wakeup()方法妹萨。如果存在年枕,則會(huì)先調(diào)用 __wakeup 方法,預(yù)先準(zhǔn)備對(duì)象需要的資源乎完。 __wakeup() 經(jīng)常用在反序列化操作中熏兄,例如重新建立數(shù)據(jù)庫(kù)連接,或執(zhí)行其它初始化操作 |
__clone() | 對(duì)象復(fù)制可以通過 clone 關(guān)鍵字來完成树姨,這將調(diào)用對(duì)象的 __clone() 方法 |
__toString() | __toString() 方法用于一個(gè)類被當(dāng)成字符串時(shí)應(yīng)怎樣回應(yīng) |
__invoke() | 當(dāng)嘗試以調(diào)用函數(shù)的方式調(diào)用一個(gè)對(duì)象時(shí)摩桶,__invoke() 方法會(huì)被自動(dòng)調(diào)用。 |
作者:captain89
鏈接:http://www.reibang.com/p/02d7f2e1ab00
感謝作者總結(jié)帽揪,僅方便自己查看轉(zhuǎn)載