摘要:特殊在,方法被對(duì)象調(diào)用執(zhí)行時(shí),會(huì)自動(dòng)確定是那個(gè)對(duì)象調(diào)用的該方法,會(huì)使用該對(duì)象為方法內(nèi)的賦值構(gòu)造析構(gòu)類(lèi),沒(méi)有作用域,作用域,只是講,函數(shù)內(nèi)和函數(shù)外。析構(gòu)在對(duì)象消失對(duì)象被銷(xiāo)毀時(shí),也會(huì)自動(dòng)執(zhí)行一個(gè)方法,稱(chēng)之為析構(gòu)方法。
相關(guān)定義
對(duì)象(object):現(xiàn)實(shí)生活中的實(shí)體,在編程語(yǔ)言中的體現(xiàn)。實(shí)體都有屬性和功能。一組數(shù)據(jù),和操作管理這些數(shù)據(jù)的操作,定義在一起就形成了一個(gè)實(shí)體,稱(chēng)之為對(duì)象。(屬性和方法的集合)
屬性(property),對(duì)象中,對(duì)象所擁有的數(shù)據(jù),稱(chēng)之為對(duì)象的屬性。
方法(method):對(duì)象中,對(duì)象所擁有的管理數(shù)據(jù)的能力,稱(chēng)之為方法。
在php中,對(duì)象通過(guò)對(duì)類(lèi)的實(shí)體化形成的對(duì)象。
類(lèi)(class): 對(duì)象的模子。 一類(lèi)的對(duì)象抽取出來(lái)。一個(gè)將對(duì)象的行為和屬性的一個(gè)抽象。就是一個(gè)定義。規(guī)定了對(duì)象應(yīng)該有哪些屬性,應(yīng)該有哪些操作(方法)。
實(shí)例化:一個(gè)動(dòng)作,根據(jù)類(lèi)中所定義的對(duì)象的特征,形成一個(gè)對(duì)象的過(guò)程。
注意: php 中,對(duì)象一定是通過(guò)類(lèi)的實(shí)例化來(lái)的。類(lèi)的地位,只是得到對(duì)象的方法。
可以使用php 預(yù)定義的類(lèi)。
stdclass . 通過(guò)實(shí)例化該類(lèi),就可以得到一個(gè)對(duì)象。
實(shí)例化: 通過(guò)關(guān)鍵字new 完成.
class 關(guān)鍵字
class 類(lèi)名 { 成員 }
在定義一個(gè)類(lèi)的時(shí),需要知道這個(gè)類(lèi)所實(shí)例化的對(duì)象,應(yīng)該具有哪些屬性和方法。
增加屬性: 對(duì)象所擁有的數(shù)據(jù),就是定義在類(lèi)中變量。
增加方法: 對(duì)象所擁有的操作,可執(zhí)行代碼就是操作.定義在類(lèi)中的函數(shù).
注意:類(lèi)中的成員(屬性和方法),需要增加訪問(wèn)修飾限定符,簡(jiǎn)單的增加--public
在聲明成員時(shí),不能直接使用變量,需要使用關(guān)鍵字來(lái)聲明
通過(guò)類(lèi)得到對(duì)象 ,操作符 new 完成.
實(shí)例化好后,典型的應(yīng)該保存在變量?jī)?nèi)
$stu = new Student();
一個(gè)類(lèi),可以實(shí)例化多個(gè)對(duì)象,多個(gè)不同的對(duì)象
對(duì)象操作屬性和方法使用操作符 ->
// 對(duì)象 -> 成員 $stu->a; // 10
注意,屬性名前$沒(méi)有了
如果存在$, 語(yǔ)法就 變成 屬性名(屬性標(biāo)識(shí)符) 由變量充當(dāng),變成了可變屬性的語(yǔ)法
$property_name = "stu_id"; echo $stu->$property_name;
屬性名,同變量名一樣,嚴(yán)格區(qū)分大小寫(xiě)。
保存數(shù)據(jù)標(biāo)識(shí)符,就區(qū)分大小寫(xiě)。
如果是結(jié)構(gòu)標(biāo)識(shí)符,就區(qū)分大小寫(xiě)。 比如:函數(shù),類(lèi),方法名。
訪問(wèn)方法:
$stu->study();
方法名,不區(qū)分大小寫(xiě)
方法名,支持可變方法,方法名有變量來(lái)代替
類(lèi)名,可以使用變量來(lái)代替。
$class_name = "Student"; $stu = new $class_name;屬性
可以在定義時(shí),為屬性直接設(shè)置初始值,但是必須已經(jīng)存在的數(shù)據(jù)(類(lèi)似于函數(shù)參數(shù)的默認(rèn)值)
如果沒(méi)有默認(rèn)值,則值為null
屬性,每個(gè)對(duì)象的同名屬性,都可以具有不同的值, 每個(gè)對(duì)象所擁有的屬性時(shí)不同的數(shù)據(jù)空間。
因?yàn)樵趯?shí)例化對(duì)象時(shí),php會(huì)為每個(gè)對(duì)象分配一個(gè)獨(dú)立的空間,保存對(duì)象的屬性
由于,常規(guī)的,每個(gè)對(duì)象,應(yīng)該擁有不同的屬性值。
建議,在得到該對(duì)象時(shí),應(yīng)該對(duì)對(duì)象所擁有的屬性,進(jìn)行初始化。
方法,也是屬于某個(gè)對(duì)象。但是通常,方法內(nèi)所操作的數(shù)據(jù),都是該對(duì)象所擁有的數(shù)據(jù)。
在使用對(duì)象調(diào)用某個(gè)方法時(shí),會(huì)自動(dòng)地將當(dāng)前對(duì)象傳遞到該方法內(nèi)(類(lèi)似于參數(shù)的傳遞)。 方法內(nèi),會(huì)自動(dòng)使用變量 $this 來(lái)接收這個(gè)對(duì)象。因此,可以在方法內(nèi),通過(guò)$this方法調(diào)用該方法的對(duì)象。
如何在方法中,訪問(wèn)對(duì)象,$this
$this,這個(gè)對(duì)象。調(diào)用該方法的對(duì)象。
$this 就是一個(gè)方法內(nèi)的局部變量。特殊在,方法被對(duì)象調(diào)用執(zhí)行時(shí),PHP會(huì)自動(dòng)確定是那個(gè)對(duì)象調(diào)用的該方法,會(huì)使用該對(duì)象為方法內(nèi)的$this賦值
構(gòu)造&析構(gòu)類(lèi),沒(méi)有作用域, 作用域,只是講,函數(shù)內(nèi)和函數(shù)外。
注意,想訪問(wèn)到對(duì)象的成員(屬性和方法),一定要先找到對(duì)象和方法。
class Student { public $stu_id; public $stu_name; public function sayName() { echo $this->stu_name; // zf var_dump($stu_name); // 報(bào)錯(cuò) Undefined variable var_dump($GLOBALS["stu_name"]); // 報(bào)錯(cuò) Undefined variable } } $stu = new Student(); $stu->stu_id = "16.7.3"; $stu->stu_name = "zf"; $stu->sayName();
類(lèi)中定義的屬性,不是相當(dāng)于類(lèi)中定義的方法的全局變量。不能直接在方法中使用屬性變量的形式訪問(wèn):
如果直接操作(輸出)這個(gè)類(lèi)名,則不會(huì)當(dāng)做類(lèi)來(lái)看待,而是當(dāng)做常量來(lái)看待。
構(gòu)造在得到對(duì)象時(shí),幾乎都需要,對(duì)對(duì)象屬性進(jìn)行初始化,而且都是一樣的操作。在一個(gè)操作中完成初始化,然后對(duì)該方法進(jìn)行多次調(diào)用。
在實(shí)例化類(lèi)得到對(duì)象時(shí)被自動(dòng)地調(diào)用
主要承擔(dān)的工作是初始化對(duì)象屬性
對(duì)象的屬性初始化
只要得到了對(duì)象,對(duì)象的屬性就應(yīng)該被賦予新的值。
如果某些屬性,在對(duì)象出現(xiàn)時(shí),可以被設(shè)置為某些特定的值。就可以在聲明類(lèi)時(shí),為聲明的屬性設(shè)置默認(rèn)值。
stu_id = $id; $this->stu_name = $name; }
調(diào)用該方法初始化
stu_id = $id; $this->stu_name = $name; } } $stu1 = new Student; // $stu1->stu_id = 100; // $stu1->stu_name = "李尋歡"; $stu1->init(100,"李尋歡"); var_dump($stu1);
再前進(jìn)一步:
是否可以在實(shí)例化后,自動(dòng)調(diào)用該初始化方法的方法。
PHP的 oop 機(jī)制,在new完成時(shí),會(huì)試著調(diào)用一個(gè)叫做 __constructor() 的方法.如果將初始化的代碼,寫(xiě)到這個(gè)方法內(nèi),就可以完成自動(dòng)初始化。
該方法,在通過(guò)類(lèi)實(shí)例化對(duì)象,也叫構(gòu)造對(duì)象時(shí),被自動(dòng)調(diào)用的,常常用于初始化對(duì)象,這個(gè)方法被叫做 構(gòu)造方法。(此方法,就是比普通方法多了一個(gè)自動(dòng)調(diào)用的功能)
只要得到了對(duì)象,對(duì)象的屬性就應(yīng)該被賦予新的值
由于不用去調(diào)用這個(gè)構(gòu)造函數(shù),如何傳參呢?
在實(shí)例化時(shí),通過(guò)在類(lèi)名后,增加實(shí)例化列表形式,為構(gòu)造函數(shù)方法傳參。stu_id = $id; $this->stu_name = $name; } } $stu1 = new Student(100,"李尋歡");此時(shí),需要注意,實(shí)例化時(shí),類(lèi)名后,可以增加括號(hào),取決于,該對(duì)象的構(gòu)造方法,是否需要參數(shù),如果不需要,則可以省略,或者是一個(gè)空括號(hào)。如果需要?jiǎng)t一定有括號(hào),括號(hào)內(nèi)是實(shí)參列表
$stu1 = new Student; $stu2 = new Student(); // 需要參數(shù) $stu2 = new Student("1000","阿飛");構(gòu)造方法的兼容性問(wèn)題
PHP5,構(gòu)造方法的名字, 就是 __construct(); 在php5之前,構(gòu)造方法名字與類(lèi)同名。為了兼容,也同時(shí)支持這個(gè)與類(lèi)同名的構(gòu)造方法class Student { public function Student ( $id, $name ) { } }如果同時(shí)出現(xiàn),如何處理
先寫(xiě)__construct(); 后寫(xiě)Student;找,__construct.
先寫(xiě)Stuendt(); 后寫(xiě)__construct();
找 __construct. 有一個(gè)錯(cuò)誤提示。
常見(jiàn)的寫(xiě)法:
public function __construct ( $id, $name ) { $this->Student($id,$name); } public function Student ( $id,$name ) { $this->stu_id = $id; $this->stu_name = $name; }構(gòu)造是這個(gè)對(duì)象來(lái)的時(shí)候的方法,對(duì)象實(shí)例化類(lèi)的時(shí)候,才形成的。
如果某些屬性,在對(duì)象出現(xiàn)時(shí),可以被設(shè)置為某些特定的值。就可以在聲明類(lèi)時(shí),為聲明的屬性設(shè)置默認(rèn)值
如果沒(méi)有定義__construct()可以不用執(zhí)行
析構(gòu)
但是一旦定義了構(gòu)造方法,那么構(gòu)造(實(shí)例化)的過(guò)程,一定要包括這個(gè)調(diào)用構(gòu)造方法的過(guò)程(構(gòu)造方法一定會(huì)執(zhí)行)。在對(duì)象消失(對(duì)象被銷(xiāo)毀時(shí)),也會(huì)自動(dòng)執(zhí)行一個(gè)方法,稱(chēng)之為析構(gòu)方法。
析構(gòu)方法名字為 __destruct();
也會(huì)自動(dòng)被調(diào)用。完全取決于這個(gè)對(duì)象是否被銷(xiāo)毀。該方法,用于釋放對(duì)象所占用的額外資源。并不是釋放對(duì)象本身.(對(duì)象本身,是由垃圾回收機(jī)制去銷(xiāo)毀) 不是對(duì)象本身的內(nèi)存空間。
public function __destruct () { // 釋放資源 mysql_close(); }什么情況下,對(duì)象會(huì)被銷(xiāo)毀:
腳本周期結(jié)束,自動(dòng)銷(xiāo)毀,幾個(gè)對(duì)象銷(xiāo)毀幾次。
銷(xiāo)毀保存該對(duì)象的變量時(shí):
unset($stu1);
保存對(duì)象的變量,被賦值了其他數(shù)據(jù)。 任何新值都可以,甚至是原來(lái)類(lèi)的新對(duì)象。都會(huì)導(dǎo)致原對(duì)象被銷(xiāo)毀。常見(jiàn)的使用是null.表示銷(xiāo)毀對(duì)象的含意
$stu = null;對(duì)象間的copy&clone對(duì)象間的復(fù)制
支持引用傳遞,不用 & 符號(hào), 因此不能通過(guò) = 賦值的形式,得到一個(gè)新的對(duì)象。克隆 clone
利用已有的對(duì)象,得到相同的新對(duì)象。
需要使用關(guān)鍵字 clone 完成。
新對(duì)象 = clone 舊對(duì)象.常見(jiàn)的操作,在克隆對(duì)象時(shí),需要對(duì)對(duì)象的某些特殊屬性進(jìn)行修改。意味著,在克隆的時(shí),需要做一些特殊的處理。
使用 在克隆時(shí),自動(dòng)調(diào)用的方法, __clone() 來(lái)實(shí)現(xiàn)。
自動(dòng)使用克隆出來(lái)的對(duì)象,來(lái)調(diào)用這個(gè)__clone()方法,意味著,該方法內(nèi)的$this,表示新對(duì)象;
public function __clone () { // $this 指向克隆對(duì)象 $this->stu_id = "1000"; } $stu3 = clone $stu1;PHP中得到新對(duì)象兩個(gè)方法
實(shí)例化(通過(guò)類(lèi)構(gòu)造對(duì)象) ,需要使用構(gòu)造方法對(duì)對(duì)象進(jìn)行初始化。
克隆(通過(guò)對(duì)象克隆新對(duì)象) ,得到一個(gè)屬性值與克隆的就對(duì)象一模一樣的對(duì)象,但是,可以通過(guò)__clone 方法進(jìn)行修改。
魔術(shù)方法
靜態(tài)成員
特定的情況下,會(huì)被自動(dòng)調(diào)用
__ 魔術(shù)方法場(chǎng)景: 學(xué)生類(lèi),每個(gè)學(xué)生是一個(gè)類(lèi)的對(duì)象,需要統(tǒng)計(jì),當(dāng)前已經(jīng)存在幾個(gè)學(xué)生?
如何定義這個(gè)計(jì)數(shù)器?
不能直接用屬于對(duì)象的屬性,每個(gè)對(duì)象所獨(dú)有的。
應(yīng)該找一個(gè)對(duì)象所共有的數(shù)據(jù)。
構(gòu)造方法靜態(tài)局部變量,也是不行,原因析構(gòu)時(shí)不能使用。public function __construct () { $this->count++; static $count = 0; $count ++; echo $coun; } public function __destruct () { $this->count--; $count--; }應(yīng)該找一個(gè)能夠被對(duì)象所共有的數(shù)據(jù)并且能夠在多個(gè)方法內(nèi)使用的變量。
使用全局變量即可,在方法內(nèi),是可以通過(guò)$GLOBALS訪問(wèn)到全局變量。public function __construct () { $GLOBALS["count"]++; } public function __destruct () { $GLOABLS["count"]--; }全局變量不應(yīng)該屬于任何的對(duì)象或者類(lèi).$count 與 類(lèi) 沒(méi)有絲毫的邏輯上的聯(lián)系.
應(yīng)該找一個(gè)能夠被對(duì)象所共有并且能夠在多個(gè)方法內(nèi)使用的變量,還應(yīng)該與當(dāng)前的對(duì)象類(lèi)有邏輯的關(guān)系的數(shù)據(jù)?
可以使用類(lèi)的靜態(tài)成員.靜態(tài)成員,指的是邏輯上被所有對(duì)象所共享,屬于類(lèi)的成員稱(chēng)之為類(lèi)的靜態(tài)成員。
靜態(tài)屬性和靜態(tài)方法
靜態(tài)屬性
保存數(shù)據(jù)的是靜態(tài)屬性,執(zhí)行功能的是靜態(tài)方法使用static 關(guān)鍵字聲明的屬性。
該靜態(tài)屬性,在邏輯上,是定義在類(lèi)上面的屬性。(與定義對(duì)象上的屬性對(duì)應(yīng)).public static $stu_count = 0;保證一個(gè)類(lèi),對(duì)應(yīng)一個(gè)屬性,意味著,該類(lèi)的所有對(duì)象共用這個(gè)屬性。
訪問(wèn)靜態(tài)屬性
通過(guò)類(lèi)來(lái)訪問(wèn),再利用靜態(tài)訪問(wèn)符號(hào)(雙冒號(hào)::,范圍解析操作符)
類(lèi)::成員
Student::$stu_count++;:: 的訪問(wèn)稱(chēng)之為靜態(tài)訪問(wèn),相對(duì)的箭頭(->)稱(chēng)為非靜態(tài)訪問(wèn)(對(duì)象訪問(wèn))
var_dump(Student::$stu_count);在訪問(wèn)時(shí),如果是在類(lèi)內(nèi)訪問(wèn):則可以使用self關(guān)鍵字,來(lái)代替當(dāng)前類(lèi).
self::$stu_count++;注意,$this和self的區(qū)別
$this表示的是這個(gè)對(duì)象。 $this->
self表示類(lèi)自己。 self::
parsent當(dāng)前父類(lèi) parent::PHP還支持的寫(xiě)法:
對(duì)象也支持靜態(tài)訪問(wèn),但是需要使用靜態(tài)訪問(wèn)符號(hào)。容易造成混淆,不建議經(jīng)常使用。$stu3::$stu_count;靜態(tài)方法靜態(tài)方法的邏輯意義,也是定義在類(lèi)上的方法。同樣,調(diào)用形式,也是通過(guò)類(lèi):: 來(lái)訪問(wèn)
定義:
public static function sayCount () { echo "run"; }訪問(wèn):
Student::sayCount();靜態(tài)方法和非靜態(tài)方法的主要區(qū)別,在于是否可以接收一個(gè)對(duì)象的執(zhí)行環(huán)境
就是是否可以為方法內(nèi)的$this 是否可以被賦值只有在對(duì)象調(diào)用方法時(shí),才能將對(duì)象的執(zhí)行環(huán)境傳遞到方法內(nèi),$this才可以被賦值.
Class Student { public static $stu_count = 0; public static function sayCount () { var_dump($this); //報(bào)錯(cuò) echo "run"; } } $stu1 = new Student(); Student::sayCount();無(wú)論靜態(tài)和非靜態(tài)方法,都是一個(gè)函數(shù),找到他并執(zhí)行即可。
一個(gè)靜態(tài)方法,只能處理靜態(tài)數(shù)據(jù)(靜態(tài)屬性)public static function sayCount () { echo self::$stu_count; echo "run"; }PHP中特殊的方法訪問(wèn)問(wèn)題
靜態(tài)方法應(yīng)該類(lèi)來(lái)調(diào)用,非靜態(tài)方法,應(yīng)該對(duì)象調(diào)用。
但是:
無(wú)論靜態(tài)還是非靜態(tài),都可以使用類(lèi)來(lái)訪問(wèn)。
不過(guò)如果類(lèi)靜態(tài)調(diào)用一個(gè)非靜態(tài)方法,會(huì)報(bào)告一個(gè)strict standards 語(yǔ)法不標(biāo)準(zhǔn)的錯(cuò)誤。
對(duì)象也可以都調(diào)用Class Student { public function fn1 () { echo "fn1"; } public static function fn2 () { echo "fn2"; } } $stu1 = new Student(); Student::fn1(); Student::fn2(); $stu1->fn1(); $stu1->fn2();區(qū)別就在于$this上
類(lèi)常量
只有在使用對(duì)象調(diào)用非靜態(tài)方法時(shí),才可以使用方法內(nèi)的$this;
靜態(tài)方法,無(wú)論如何也不能對(duì)$this做處理
而非靜態(tài)方法,只有確定了對(duì)象,才能確定$this的值類(lèi)中,保存運(yùn)行運(yùn)行周期內(nèi),不變的數(shù)據(jù)。就是常量。
定義
const 關(guān)鍵字
const 常量名 = 常量值
沒(méi)有訪問(wèn)修飾限定符.const PI = 3.14;訪問(wèn)
類(lèi)::常量名
把屬性值,固定值,定義成常量。self::PI;常見(jiàn),類(lèi)中 屬性的選項(xiàng), 多定義成 常量。
類(lèi)中可以定義的成員一共有
常量,靜態(tài)屬性,靜態(tài)方法,非靜態(tài)屬性,非靜態(tài)方法
除了以上5個(gè),類(lèi)中,不能直接出現(xiàn)其他語(yǔ)句,例如echo的執(zhí)行性語(yǔ)句,var_dump(), 等等
簡(jiǎn)化一點(diǎn):常量,屬性,方法$this 表示當(dāng)前對(duì)象
永遠(yuǎn)表示$this所在類(lèi)的對(duì)象么?
不是,因?yàn)?this的值,不取決于$this所在的類(lèi),而是$this所在方法在被調(diào)用時(shí)執(zhí)行對(duì)象(執(zhí)行環(huán)境)。方法的執(zhí)行環(huán)境(context),當(dāng)前方法是在哪個(gè)對(duì)象的環(huán)境下執(zhí)行,方法在哪個(gè)對(duì)象的環(huán)境下執(zhí)行,該方法內(nèi)的$this 就表示哪個(gè)對(duì)象。
繼承和重寫(xiě) 繼承
執(zhí)行環(huán)境向下環(huán)境.一個(gè)對(duì)象擁有或者使用另一個(gè)對(duì)象的成員信息,稱(chēng)之為這個(gè)對(duì)象繼承自另一個(gè)對(duì)象。
PHP中,通過(guò)在類(lèi)上,使用特殊的操作達(dá)到目的。
繼承是對(duì)象的概念,只不過(guò)語(yǔ)法上面要通過(guò)類(lèi)來(lái)實(shí)現(xiàn)。通過(guò)在在定義類(lèi)時(shí),利用extends 來(lái)指明當(dāng)前類(lèi)的對(duì)象 , 繼承那個(gè)類(lèi)的對(duì)象。
class C { public $p_c = "value C"; } class D extends C { public $p_d = "value D"; } $d = new D(); var_dump($d->p_d); var_dump($d->p_c);繼承,指的是兩個(gè)對(duì)象之間,那么哪有這兩個(gè)對(duì)象?
class C { public $p_c = "value C"; } class D extends C { public $p_d = "value D"; } $d = new D(); var_dump($d instanceof D); // true var_dump($d instanceof C); // true相關(guān)概念
class D extends C {}
D 類(lèi)對(duì)象 繼承自 C 類(lèi)對(duì)象
父類(lèi):被繼承的類(lèi),C類(lèi)
子類(lèi):需要繼承的類(lèi),D類(lèi)功能上:
基類(lèi):C類(lèi)是D類(lèi)的基類(lèi)
擴(kuò)展類(lèi):D類(lèi)是C類(lèi)的擴(kuò)展類(lèi)繼承概念體現(xiàn)在對(duì)象上,語(yǔ)法體現(xiàn)在類(lèi)上。
語(yǔ)法意義就是,面向?qū)ο笳Z(yǔ)法中的,代碼的重用PHP是單繼承
單繼承,一個(gè)類(lèi)只能繼承自另一個(gè)類(lèi),不能同時(shí)繼承多個(gè)類(lèi)。但是一個(gè)類(lèi)可以被多個(gè)類(lèi)繼承。繼承的目的:
重寫(xiě)override
在于擴(kuò)展,或使用某個(gè)類(lèi)已經(jīng)存在的操作和數(shù)據(jù)。
繼承,在編程上,可以是理解成OOP代碼的共用。只有發(fā)生在繼承上,才會(huì)出現(xiàn),是一個(gè)現(xiàn)象。
如果子類(lèi),與父類(lèi),出現(xiàn)同名的成員(屬性方法),則在實(shí)例化子類(lèi)對(duì)象時(shí),只會(huì)得到子類(lèi)中定義的成員,稱(chēng)之為重寫(xiě)。成員沖突
繼承時(shí),如果發(fā)生成員沖突,PHP的處理方式,為重寫(xiě)。就是子類(lèi)同名成員會(huì)覆蓋父類(lèi)的同名成員。不能看到父類(lèi)的成員。class P { public $name = "p"; public function sayNmae () { echo "parent::name", $this->name; } } class C extends P { public $name = "C"; public function sayName () { echo "self::name",$this->name; } } $obj = new C(); echo $obj->name; // C echo "
"; $obj->sayName(); // self::nameC某些情況下,重寫(xiě)時(shí)一定發(fā)生的,例如構(gòu)造等。
如果需要,強(qiáng)制執(zhí)行被重寫(xiě)的父類(lèi)方法,可以顯式的使用父類(lèi)來(lái)調(diào)用相應(yīng)的父類(lèi)方法即可。public function __construct () { P::__construct(); }可以使用一個(gè)關(guān)鍵字,在類(lèi)內(nèi),代替當(dāng)前類(lèi)的父類(lèi)。
parent 關(guān)鍵字,代替父類(lèi)。
一旦重寫(xiě),父類(lèi)代碼就不會(huì)在執(zhí)行了。P::__construct(); parent::__construct();如果說(shuō)父類(lèi)的構(gòu)造需要相應(yīng)的參數(shù),則需要將再調(diào)用時(shí),將父類(lèi)的構(gòu)造方法需要的參數(shù),也傳遞到方法內(nèi)。
class GoodsBook extends Goods { public $page; public function __construct ( $name, $price, $pages ) { parent::__constuct($name, $price); $this->pages = $pages; } }一般2到3層的繼承,就基本上可以
instanceof 操作符
用于判斷一個(gè)對(duì)象是否是某個(gè)類(lèi)的實(shí)例
$this的確定只有在使用對(duì)象調(diào)用非靜態(tài)方法時(shí),才可以使用$this!
哪個(gè)對(duì)象調(diào)用方法,方法內(nèi)$this就是那個(gè)對(duì)象。
對(duì)象環(huán)境,是可以向下傳遞。
如果當(dāng)前方法內(nèi),已經(jīng)確定了對(duì)象環(huán)境。在該方法內(nèi),如果出現(xiàn)了靜態(tài)調(diào)用非靜態(tài)方法,此時(shí)當(dāng)前的對(duì)象環(huán)境,會(huì)傳遞到靜態(tài)方法調(diào)用的非靜態(tài)方法中。
class A { public function in_a () { var_dump($this); } } class B { public function in_b () { var_dump($this); // B 實(shí)例化對(duì)象 echo "PHP連接MySql 設(shè)置屬性和連接方法
"; A::in_a(); // B 實(shí)例化對(duì)象 } } $obj = new B(); $obj->in_b();構(gòu)造方法內(nèi),使用數(shù)組作為參數(shù),如果參數(shù)過(guò)多,便于管理。
利用參數(shù),為對(duì)象屬性進(jìn)行賦值
常見(jiàn)的,在實(shí)際操作中:為屬性設(shè)置默認(rèn)值。如果用戶在實(shí)例化時(shí),傳遞了屬性參數(shù),則使用用戶傳遞的,否則使用默認(rèn)值。// $params Array public function __construct ( $params ) { $this->host = isset($params["host"]) ? $params["host"] : "127.0.0.1"; $this->port = isset($params["port"]) ? $params["port"] : "3306"; $this->user = isset($params["user"]) ? $params["user"] : "root"; $this->pass = isset($params["pass"]) ? $params["pass"] : ""; $this->charset = isset($params["charset"]) ? $params["charset"] : "utf8"; $this->dbname = isset($params["dbname"]) ? $params["dbname"] : ""; $this->prefix = isset($params["prefix"]) ? $params["prefix"] : ""; }連接應(yīng)該在構(gòu)造方法內(nèi)完成
要求,一個(gè)功能,盡量使用一個(gè)方法獨(dú)立完成,一個(gè)大的功能,是由多個(gè)小功能組合起來(lái)。// 連接數(shù)據(jù)庫(kù) public function connect () { mysql_connect("$this->host:$this->port",$this->user,$this->pass); }為當(dāng)前的功能類(lèi),增加一個(gè)屬性,保存這個(gè)鏈接資源
// 運(yùn)行時(shí)生成的信息 public $link;在連接成功后,為屬性賦值
連接失敗,給出提示public function connect () { if ( $link = mysql_connect("$this->host:$this->port",$this->user,$this->pass) ) { $this->link = $link; } else { echo "連接失敗"; exit; } }設(shè)置字符集,提取執(zhí)行SQL設(shè)置字符集
// 設(shè)置字符集 public function setCharset () { $query = "set names $this->charset"; if ( mysql_query($query) ) { // 成功 } else { // 失敗 echo "字符串設(shè)置失敗"; exit; } }執(zhí)行sql語(yǔ)句
// 執(zhí)行SQL語(yǔ)句 public function query ( $query ) { if ( $reslut = mysql_query($query,$this->link) ) { // 執(zhí)行成功 return $reslut; } else { // 執(zhí)行錯(cuò)誤 ,給出提示 echo "SQL執(zhí)行錯(cuò)誤,錯(cuò)誤信息:
"; echo "出錯(cuò)的SQL為:", $query ,"
link), "
"; echo "錯(cuò)誤的信息為:", mysql_error($this->link), "
"; // 簡(jiǎn)單錯(cuò)誤處理,一旦出錯(cuò),直接停止掉腳本執(zhí)行 die; // 如果在完整的處理過(guò)程中, 出錯(cuò)應(yīng)該余下代碼繼續(xù)執(zhí)行 // 需要判斷是否執(zhí)行成功 ,返回false return false; } }
"127.0.0.1","port","3306","user",); public function __construct( $params ){ //對(duì)屬性初始化 //如果配置項(xiàng)選項(xiàng)存在,則使用用戶的,否則使用默認(rèn)的。 $this->host = isset( $params["host"] ) ? $params["host"] : "127.0.0.1" ; $this->port = isset( $params["port"] ) ? $params["port"] : "3306"; $this->user = isset( $params["user"] ) ? $params["user"] : "root"; $this->pass = isset( $params["pass"] ) ? $params["pass"] : ""; $this->charset = isset( $params["charset"] ) ? $params["charset"] : "utf8"; $this->dbname = isset( $params["dbname"] ) ? $params["dbname"] : ""; $this->prefix = isset( $params["prefix"] ) ? $params["prefix"] : ""; //連接 $this->connect(); //設(shè)置字符集 $this->setCharset(); //選擇默認(rèn)數(shù)據(jù)庫(kù) $this->selectDB(); } // 連接數(shù)據(jù)庫(kù)服務(wù)器 public function connect(){ if( $link = mysql_connect("$this->host:$this->port",$this->user,$this->pass) ){ //連接成功 $this->link = $link; } else { //連接失敗 echo "連接失敗 !"; exit; } } // 設(shè)置字符集 public function setCharset(){ $query = "set names $this->charset"; $this->query($query); } // 選擇默認(rèn)數(shù)據(jù)庫(kù) public function selectDB(){ $query = "use $this->dbname"; $this->query($query); } // 執(zhí)行SQL語(yǔ)句 // @param $query string 需要執(zhí)行的SQL語(yǔ)句. // @return mixed 成功返回資源結(jié)果集或者true. 失敗返回false. public function query( $query ){ if( $result = mysql_query($query,$this->link) ){ //執(zhí)行成功 return $result; } else { //執(zhí)行失敗 //給出錯(cuò)誤提示 echo "SQL執(zhí)行出錯(cuò),錯(cuò)誤信息如下:訪問(wèn)控制說(shuō)明 訪問(wèn)修飾限定符
"; echo "出錯(cuò)的SQL語(yǔ)句為:",$query,"
"; echo "錯(cuò)誤的代碼為:",mysql_errno($this->link),"
"; echo "錯(cuò)誤的信息為:",mysql_error($this->link),"
"; //簡(jiǎn)單錯(cuò)誤處理,一旦出錯(cuò),直接停止腳本執(zhí)行. die; //如果再完整的處理過(guò)程中,出錯(cuò)應(yīng)該余下的代碼繼續(xù)執(zhí)行。 //需要判斷是否執(zhí)行成功,返回false. // return false; } } } $db = new MYSQLDB( array("host"=>"127.0.0.1","port"=>3306,"user"=>"root","pass"=>"") ); var_dump($db); ?>public , protacted, private
用于描述,一個(gè)成員(屬性,方法)在哪里才能被訪問(wèn)的。php5中,要求所有的成員(屬性和方法)都應(yīng)該受訪問(wèn)修飾的控制,聲明時(shí),前面都應(yīng)該存在訪問(wèn)修飾限定符
存在例外,為了兼容.
在聲明屬性時(shí),可以使用特殊的 var 關(guān)鍵字.相當(dāng)于使用public來(lái)聲明.
class Student { var $stu_id; }方法中,聲明時(shí),可以省略訪問(wèn)修飾限定符.相當(dāng)于public.
class Student { function sayCount () {} }public ,公共的,成員在類(lèi)內(nèi),繼承鏈上類(lèi)內(nèi),和類(lèi)外都可以訪問(wèn)到(任何地方)
protacted , 保護(hù)的,就是類(lèi)內(nèi)和繼承鏈上的類(lèi)內(nèi) 都可以訪問(wèn).
private , 私有的, 類(lèi)內(nèi).PHP是采用類(lèi)的概念,進(jìn)行成員的限制訪問(wèn)的。
PHP將訪問(wèn)的代碼,分成三大區(qū)域:類(lèi)內(nèi),類(lèi)外,繼承鏈上的類(lèi)內(nèi)。
類(lèi)內(nèi): 定義該成員所在類(lèi)的內(nèi)部.
繼承鏈上的類(lèi)內(nèi)
類(lèi)外類(lèi)外訪問(wèn):只有公共可以訪問(wèn)
類(lèi)內(nèi)訪問(wèn):類(lèi)中所定義的方法內(nèi)
所有的限定都可以繼承鏈上的類(lèi)內(nèi):
保護(hù)的和公共的可以被訪問(wèn),而私有的不可以被訪問(wèn).根據(jù):成員在哪里定義 與 成員在哪里訪問(wèn) 來(lái)決定 類(lèi)內(nèi) , 類(lèi)外 還是 繼承鏈上的類(lèi)內(nèi)。
注意
受保護(hù),繼承鏈上的類(lèi)內(nèi)
父類(lèi)內(nèi)定義,子類(lèi)內(nèi)訪問(wèn). 反過(guò)來(lái),子類(lèi)內(nèi)定義父類(lèi)內(nèi)可以訪問(wèn).私有成員的問(wèn)題
出現(xiàn)在 私有屬性 的重寫(xiě)上
PHP會(huì)記錄所有的私有屬性,同時(shí)會(huì)記錄私有屬性所在的類(lèi),在不同類(lèi)內(nèi)訪問(wèn)不同的私有屬性時(shí)是不同的。而, 公共的和 受保護(hù)的, 則只會(huì)記錄一次,明顯的被重寫(xiě)了;
寫(xiě)繼承的時(shí)候,如果是有屬性被重寫(xiě)了,要注意到,當(dāng)前所訪問(wèn)的私有屬性是哪一個(gè)私有屬性.私有成員不能被重寫(xiě)。意味著,在相應(yīng)的私有屬性定義在類(lèi)中,才能訪問(wèn)到相應(yīng)的私有屬性。
建議是:如果需要通過(guò)繼承,就使用保護(hù)的,少用私有的。在沒(méi)有繼承時(shí),盡量使用私有的。
重寫(xiě)的問(wèn)題,要先明確訪問(wèn)的究竟是哪里所定義的。
在重寫(xiě)時(shí),如果重寫(xiě)成員的訪問(wèn)級(jí)別不一致。子類(lèi)的級(jí)別比父類(lèi)的級(jí)別,相等或者弱,可以。強(qiáng),不行。
封裝怎么使用訪問(wèn)修飾,如何選擇
原則:盡量提高,類(lèi)對(duì)其成員的控制能力. 能用private,盡量使用private,能用protected就不用public.
一個(gè)原則,盡量體現(xiàn)封裝性。封裝性,指的是,盡量隱藏內(nèi)部實(shí)現(xiàn),而僅僅開(kāi)發(fā)外部操作接口!
語(yǔ)法上,就是,將不需要外部使用的屬性,方法,都私有化(保護(hù)化),而僅僅留下一些必要的公共方法!選擇訪問(wèn)修飾限定符,體現(xiàn)oop思想的封裝性的特點(diǎn).
封裝性:隱藏對(duì)象的內(nèi)部實(shí)現(xiàn)細(xì)節(jié),只提供外部操作方法。
對(duì)象的外部操作方法,稱(chēng)之為對(duì)象的接口(interface). 接口在語(yǔ)法上,就是一些公共的方法.
封裝:只有操作接口可以被看到,內(nèi)部實(shí)現(xiàn)都被隱藏.經(jīng)典的:幾乎所有的屬性和大部分的方法都是私有(如果有繼承的話,會(huì)有受保護(hù)).只有一些供外部調(diào)用者使用的方法,是公共的.
類(lèi): 繼承和實(shí)例化
類(lèi): 調(diào)用其靜態(tài)成員
類(lèi): 作為其他類(lèi)的基礎(chǔ)類(lèi),被繼承
兩大功能:實(shí)例化對(duì)象, 基礎(chǔ)類(lèi)被繼承抽象類(lèi): 只能被繼承,不能被實(shí)例化對(duì)象
final類(lèi)
final類(lèi): 只能被實(shí)例化,不能被繼承該類(lèi),只能被實(shí)例化對(duì)象不能用于被繼承。
設(shè)計(jì)時(shí),該類(lèi)不能再擴(kuò)展,就應(yīng)該通過(guò)語(yǔ)法,final限制,其它用戶擴(kuò)展該類(lèi).
最終,在繼承鏈條上, 最末的一個(gè)類(lèi),其下不能再出現(xiàn)子類(lèi),意味著不能被繼承。定義
在 class 前 加 final關(guān)鍵字,即可.final class GoodsBook extends Goods {}如果繼承該類(lèi),會(huì)報(bào)錯(cuò)
因此,final 類(lèi)的作用,是在語(yǔ)法上,人為的限定哪些類(lèi)不能被繼承.
final 關(guān)鍵字的另一個(gè)用法, 用于限制方法,在所屬類(lèi),被繼承時(shí),該方法不能被重寫(xiě).
// 所有商品輸出價(jià)格方式一致 final public function sayPrice() { echo "¥",$this->shop_price; }抽象類(lèi)abstract有一種類(lèi),只能被繼承,不能被實(shí)例化對(duì)象。原因就是這個(gè)類(lèi)的定義不完整. (有了一半的藏寶圖,需要找到其它的藏寶圖,補(bǔ)充完整) 為什么會(huì)不完整? 因?yàn)镻HP支持定義一種,只有方法的聲明部分,而沒(méi)有方法的實(shí)現(xiàn)部分的不完整方法。(類(lèi)所包含的元素,不完整,可以不完整的是方法)。
如果某個(gè)類(lèi),包含了這種不完整的方法,就不是一個(gè)完整的類(lèi),就不能實(shí)例化對(duì)象!
不完整的類(lèi), 稱(chēng)之為 抽象類(lèi). abstract class
所包含的不完整的方法,稱(chēng)之為:抽象方法. abstract method
定義
包含了抽象方法的類(lèi),就是抽象類(lèi)語(yǔ)法
定義抽象方法,利用一個(gè)叫 abstruct 的關(guān)鍵字,告知PHP某個(gè)方法時(shí)一個(gè)抽象方法,沒(méi)有方法體abstract public funciton sayName(); // 要注意分號(hào)定義一個(gè)抽象類(lèi)
如果一個(gè)類(lèi)包含了抽象方法,也就是抽象類(lèi),因此也需要使用 abstruct 關(guān)鍵字聲明.沒(méi)有實(shí)例化的能力
實(shí)例化報(bào)錯(cuò)
只有被繼承的能力
如果繼承某個(gè)抽象類(lèi)的類(lèi)是非抽象類(lèi)的話,就一定要將不完整的抽象方法實(shí)現(xiàn)。否則該類(lèi)也應(yīng)該是一個(gè)抽象類(lèi).抽象類(lèi)的具體功能
1:限制子類(lèi)的結(jié)構(gòu)由于抽象類(lèi),只能被繼承,而且如果其子類(lèi)不是一個(gè)抽象類(lèi)的話,要求必須實(shí)現(xiàn)抽象類(lèi)所定義的抽象方法,因此抽象類(lèi)的功能也可以理解成,用于限制其子類(lèi)(擴(kuò)展類(lèi))的結(jié)構(gòu).
就可以保證,同一系列的處理類(lèi),所擁有的結(jié)構(gòu)是一致的。將來(lái)可以實(shí)現(xiàn)無(wú)縫對(duì)接,任意切換(熱插拔) 。
2:可以限制
方法名,參數(shù)個(gè)數(shù).
訪問(wèn)修飾控制.
擴(kuò)展類(lèi)(子類(lèi))的權(quán)限限制,弱于抽象類(lèi)抽象類(lèi)功能
接口 interface
在可以為子類(lèi)(擴(kuò)展類(lèi))提供共用操作的同時(shí),限制子類(lèi)(擴(kuò)展類(lèi))所擁有的方法的結(jié)構(gòu).
犧牲掉了實(shí)例化對(duì)象的功能.一個(gè)對(duì)象的封裝,分為兩大部分
內(nèi)部實(shí)現(xiàn)
就是操作接口
PHP中,可以規(guī)定,一個(gè)對(duì)象應(yīng)該具有哪些公共的外部操作,使用interface來(lái)規(guī)定
公共的方法就是接口
用于規(guī)定一個(gè)對(duì)象應(yīng)該擁有哪些公共的操作方法(接口),這個(gè)東西也叫接口(公共操作方法的集合).
接口(interface 結(jié)構(gòu),公共方法的集合)公共方法(接口方法)
定義:用于限定某個(gè)對(duì)象所必須擁有的公共操作方法的一種結(jié)構(gòu),稱(chēng)之為接口(interface).
就是用于限制公共方法。語(yǔ)法:
定義這個(gè)接口結(jié)構(gòu),使用interface 關(guān)鍵字.接口定義的都是公共的方法interface 接口名 { 公共操作方法列表 } interfece I_Goods { public function sayName(); public function sayPrice(); }注意:
接口方法,必須都是公共的
接口內(nèi)只能有公共方法,不能存在成員變量屬性interfece I_Goods { public $goods_name; //報(bào)錯(cuò) public function sayName(); public function sayPrice(); }接口內(nèi),只能含有未被實(shí)現(xiàn)的方法,也叫抽象方法,但是不用abstract關(guān)鍵字().
如果是一個(gè)完整方法,會(huì)報(bào)錯(cuò)。使用接口
限制對(duì)象的必要的公共操作
類(lèi)實(shí)現(xiàn)接口 (實(shí)現(xiàn)--把你想做的事完成). 利用關(guān)鍵字, implements;class Goods implements I_Goods {}這樣,實(shí)現(xiàn)該接口的類(lèi),必須實(shí)現(xiàn)接口內(nèi)所有的抽象方法。而且可以肯定,該方法一定是公共的外部操作方法
// 定義接口 interface I_Goods { public function sayName(); public function sayPrice(); } // 實(shí)現(xiàn)接口 class Goods implements I_Goods { public $goods_name; public $shop_price; public function __construct ( $name, $price ) { $this->goods_name = $name; $this->shop_price = $price; } public function sayName () { echo $this->goods_name; } public function sayPrice () { } } $goods = new Goods("php", 234); $goods->sayName(); $goods->sayPrice();類(lèi)似于抽象類(lèi),比較與接口的區(qū)別:
抽象類(lèi)與普通類(lèi)之間是繼承關(guān)系
普通類(lèi)繼承抽象了,第一可以得到抽象類(lèi)中的已有的常規(guī)成員,第二才需要實(shí)現(xiàn)抽象方法(也不一定是public)接口與普通類(lèi)之間是實(shí)現(xiàn)關(guān)系
普通類(lèi)實(shí)現(xiàn)了接口,只能將其沒(méi)有實(shí)現(xiàn)的公共方法實(shí)現(xiàn)接口只用于定義 公共的方法。 而抽象類(lèi),什么都可以有。
多實(shí)現(xiàn)
上面的功能,理論上講,可以通過(guò)抽象類(lèi)完成。 但是抽象類(lèi),不專(zhuān)業(yè)
接口專(zhuān)業(yè)體現(xiàn)在實(shí)現(xiàn)上,因?yàn)镻HP支持多實(shí)現(xiàn),而僅支持單繼承.class Goods implements I_Goods, I_Shop { }繼承和實(shí)現(xiàn)區(qū)別
繼承:體現(xiàn)的是將別的對(duì)象已經(jīng)存在的東西,拿來(lái)自己用
實(shí)現(xiàn):將某個(gè)地方的規(guī)定,自己來(lái)完成接口之間,也可以繼承
interface I_Shop extend I_Goods { public function saySafe(); }抽象類(lèi) pk 接口
繼承 pk 實(shí)現(xiàn)PHP對(duì)接口的支持,可以定義常量
interface I_Shop extend I_Goods { const PAI = 3.14; }通過(guò)類(lèi)去訪問(wèn)
class Goods implements I_Shop {}
echo Goods::PAI;辨別
繼承應(yīng)用 表操作模型
接口是不是類(lèi) ?
接口不是類(lèi),接口就是獨(dú)立的一種結(jié)構(gòu),適用于限制類(lèi)的結(jié)構(gòu)。但是可以理解成"接口類(lèi)似于一個(gè)所有的方法都是公共的抽象方法,而且沒(méi)有其它成員的抽象類(lèi)",并不是一個(gè)概念。
class_exists(); 判斷一個(gè)類(lèi)是否存在?項(xiàng)目中操作數(shù)據(jù)庫(kù)的典型模式: 數(shù)據(jù)操作模型(model).
常見(jiàn)的操作
PHP項(xiàng)目中,由于不同的數(shù)據(jù)實(shí)體對(duì)應(yīng)的業(yè)務(wù)邏輯是不同的,通常的操作數(shù)據(jù)的方法:為每張表創(chuàng)建一個(gè)操作對(duì)象class BaseTable {} class GoodsTable extends BaseTable {} class CrtegoryTable extends BaseTable {}如果兩個(gè)類(lèi)有具體的關(guān)系,使用繼承.
聚合如果是多個(gè)類(lèi)需要使用另一個(gè)類(lèi),所提供的功能,還有一種方式,稱(chēng)之為聚合.
class MySQLDB { public function query () { } } class BrandTable { public $db; public function __construct () { $this->db = new MysqlDB(); $this->db->query(); } } $brand = new BarndTable(); $brand->db;如果,BrandTbale 類(lèi) 對(duì)象,需要使用MySQLDB類(lèi)對(duì)象的相應(yīng)功能,可以BrandTable對(duì)象內(nèi),增加一個(gè)屬性保存MySQLDB類(lèi)對(duì)象。打到 BarndTable使用MySQLDB 對(duì)象的功能目的
這種方式,稱(chēng)之為 對(duì)象的聚合。既然聚合 和 繼承 都可以達(dá)到 共用一個(gè)類(lèi)功能的目的,使用的標(biāo)準(zhǔn)
如果說(shuō)兩個(gè)類(lèi)之間存在邏輯關(guān)系上的必然聯(lián)系,就建議使用繼承。
反之,如果是邏輯上,一個(gè)對(duì)象使用另一個(gè)對(duì)象,此時(shí)應(yīng)該使用對(duì)象間的聚合。優(yōu)劣性
自動(dòng)加載機(jī)制
使用繼承,可以增加類(lèi)之間的聯(lián)系,增加關(guān)聯(lián)性。
而使用聚合,可以降低類(lèi)之間的關(guān)聯(lián)性,可以降低耦合性!保存類(lèi)的方法:
將類(lèi)的定義代碼,放置在一個(gè)獨(dú)立的文件中. 如果需要該類(lèi),則直接調(diào)用.為了識(shí)別,某個(gè)類(lèi)定義文件,常見(jiàn)的,類(lèi)定義文件的命名方式為:
類(lèi)名.class.php使用時(shí)引入:
require("./MySQLDB.php");思考:
如果項(xiàng)目中,多處使用OOP,導(dǎo)致整個(gè)項(xiàng)目中,出現(xiàn)多個(gè) xxx.class.php 文件,每當(dāng)需要都需要引入 ?使用自動(dòng)加載,按需引入類(lèi)文件
需要解決的問(wèn)題:
1,什么時(shí)候需要類(lèi)?
實(shí)例化時(shí),靜態(tài)調(diào)用時(shí),一個(gè)類(lèi)被繼承時(shí)如果使用其子類(lèi)時(shí)。
2,在需要時(shí),應(yīng)該主動(dòng)require 系列的代碼, 才可能加載成功,如何做到需要自動(dòng)執(zhí)行某段代碼?
3,需要的是類(lèi),而載入的是文件,需要解決如何通過(guò) 類(lèi) 來(lái)確定 類(lèi)文件的所在文件.PHP解決了前2個(gè)問(wèn)題,需要解決第三個(gè)問(wèn)題。
PHP提供了一個(gè)機(jī)制(功能),可以在需要某個(gè)類(lèi),但是沒(méi)有載入這個(gè)定義類(lèi)時(shí).會(huì)自動(dòng)調(diào)用某個(gè)函數(shù)。并同時(shí)將當(dāng)前所需要的類(lèi)名,作為參數(shù)傳遞到這個(gè)自動(dòng)調(diào)用的函數(shù)內(nèi)。
PHP提供一個(gè)時(shí)機(jī),完成自動(dòng)加載。
這個(gè)函數(shù)默認(rèn)不存在,需要用戶自己定義。 函數(shù)名為 __autoload();function __autolaod ( $class_name ) { var_dump($class_name); require $class_name.".class.php"; }一旦函數(shù)存在,在特定情況(需要類(lèi)但是沒(méi)有找到),則PHP內(nèi)部會(huì)自動(dòng)調(diào)用__autoload().執(zhí)行在函數(shù)體定義的函數(shù),從而完成加載類(lèi)所在的文件。
分工:
用戶腳本:定義函數(shù),接收需要的類(lèi)名作為參數(shù),函數(shù)需要實(shí)現(xiàn)通過(guò)類(lèi)名找到類(lèi)所在的文件,將其載入即可!
PHP核心(Zend Engine):判斷是否需要類(lèi),并且判斷該類(lèi)是否已經(jīng)載入了,如果需要但是沒(méi)有載入,則嘗試調(diào)用用戶定義的__autoload()函數(shù),并將需要的類(lèi)名傳遞即可!__autoload 函數(shù)名得到是類(lèi)名
而載入的是類(lèi)文件定義的文件。
因此,自動(dòng)加載機(jī)制的前提:必須要能夠通過(guò)類(lèi)名,推導(dǎo)出,類(lèi)所在的文件才可以。(定義類(lèi)文件時(shí),要有規(guī)律)注意:
對(duì)象序列化
PHP提供了加載代碼的執(zhí)行時(shí)機(jī)。用戶腳本,需要完成加載代碼,其中核心任務(wù)是,通過(guò)所得到的類(lèi)名,找到類(lèi)定義所在的文件。序列化,反序列化(串行化,反串行化)
數(shù)據(jù)持久化
在數(shù)據(jù)保存,面臨一個(gè)問(wèn)題:數(shù)據(jù)格式。PHP的數(shù)據(jù)有八種類(lèi)型之多,文件只能存儲(chǔ)字符串。
一旦數(shù)據(jù)類(lèi)型不是字符串類(lèi)型。就會(huì)導(dǎo)致數(shù)據(jù)不能原樣保存,不能取得原始數(shù)據(jù)。
如何解決
任何形式的數(shù)據(jù),都可以存儲(chǔ)到文件中,并且,在取出來(lái)時(shí),原樣得到數(shù)據(jù)。
在保存,與讀取時(shí),對(duì)數(shù)據(jù)進(jìn)行轉(zhuǎn)換與反轉(zhuǎn)換。序列化
serialize();
原始數(shù)據(jù)轉(zhuǎn)成能夠記錄的原始數(shù)據(jù)信息的字符串反序列化
unserialize();
通過(guò)序列化的字符串結(jié)果,將原始數(shù)據(jù)還原!只有在涉及到,數(shù)據(jù)需要被存儲(chǔ),或者 傳輸時(shí), 需要對(duì)數(shù)據(jù)進(jìn)行序列化。
注意的數(shù)據(jù)類(lèi)型都可以被序列化與反序列外。資源是例外!
對(duì)象的序列化與反序列化
在對(duì)象被反序列化時(shí),需要找到當(dāng)前對(duì)象所屬的類(lèi)才可以被完美的反序列化,如果不能找到屬于的類(lèi),那么會(huì)變成php內(nèi)置類(lèi):__PHP_Incompleta_Class(不完整類(lèi))的一個(gè)對(duì)象.
因此,只要在反序列話之前,將類(lèi)載入即可。反序列化,也會(huì)觸發(fā)自動(dòng)加載機(jī)制。
在序列化時(shí),可以自定義需要序列化的屬性名單!
通過(guò)對(duì)象的特殊的方法 __sleep();
該方法會(huì)在對(duì)象被序列化時(shí),自動(dòng)調(diào)用,不需要參數(shù),返回一個(gè)數(shù)組,每個(gè)元素,表示一個(gè)屬性名,數(shù)組內(nèi)存在的屬性名,就會(huì)被序列化。反之則不會(huì)被序列化。// 在序列化時(shí)被調(diào)用 // 用于負(fù)責(zé)指明那些屬性需要被序列化 // @return array public function __sleep () { return array("host", "port", "user", "pass", "charset", "dbname"); }在反序列化時(shí),可以自動(dòng)再次執(zhí)行某些代碼,從而完成某些資源的初始化!
通過(guò) 對(duì)象方法:__wakeup()方法
會(huì)在 對(duì)象被反序列過(guò)程中自動(dòng)調(diào)用,所負(fù)責(zé)的功能,執(zhí)行反序列話(醒來(lái)之后)的初始化工作!// 在反序列化時(shí)調(diào)用 // 用于 對(duì)對(duì)象的屬性進(jìn)行初始化 public function __wakeup () { // 連接數(shù)據(jù)庫(kù) $this->connect(); // 設(shè)置字符集 $this->setCharset(); // 設(shè)置默認(rèn)數(shù)據(jù)庫(kù) $this->selectDB(); }PHP 自動(dòng)調(diào)用, 用戶腳本只需要定義。在特定的功能調(diào)用特定的方法。稱(chēng)之為:魔術(shù)方法。
單例模式單例,單個(gè)實(shí)例。設(shè)計(jì)模式的一種,通過(guò)一種語(yǔ)法的設(shè)計(jì),保證類(lèi)(對(duì)象)上具有某些特征,這樣的一種語(yǔ)法實(shí)現(xiàn),就可以稱(chēng)之為設(shè)計(jì)模式。
其中,設(shè)計(jì)可以保證一個(gè)類(lèi),有且只有一個(gè)對(duì)象,這種設(shè)計(jì)模式就稱(chēng)之為單例模式。單例模式的作用,單例的設(shè)計(jì),是適用于使用一個(gè)對(duì)象可以完成所有業(yè)務(wù)邏輯的類(lèi)
典型的實(shí)現(xiàn),在類(lèi)上,做限制:三私一公。
某個(gè)類(lèi)只要實(shí)例化一次就可以完成所有的業(yè)務(wù)邏輯!
但是實(shí)例化多次也可以。顯然,應(yīng)該保證對(duì)象被實(shí)例化一次,從而節(jié)約資源空間!
MySQLDB類(lèi),如何設(shè)計(jì),從而達(dá)到保證該類(lèi) 有且只有一個(gè)對(duì)象.
原因:使用者,可以無(wú)限次的去實(shí)例化 這個(gè)類(lèi)。三私一公
1:限制,用戶無(wú)限制執(zhí)行new
在實(shí)例化的過(guò)程中,需要執(zhí)行構(gòu)造方法,如果執(zhí)行不成功,那么實(shí)例化過(guò)程失敗。因此,將構(gòu)造方法,私有化(保護(hù)化),可以保證在類(lèi)外進(jìn)行實(shí)例化的工作都會(huì)失敗。class MySQLDB { private function __construct () { } }2,類(lèi),不能實(shí)例化了,不能再類(lèi)外實(shí)例化,可以在類(lèi)內(nèi)實(shí)例化,類(lèi)內(nèi)執(zhí)行new操作。
因此:在類(lèi)中,增加一個(gè)公共的靜態(tài)的方法,在方法內(nèi),執(zhí)行new實(shí)例化類(lèi)對(duì)象。
class MySQLDB { // 私有化構(gòu)造函數(shù) private function __construct () { } // 執(zhí)行new public static function getInstance () { return new MySQLDB(); } } $db1 = MySQLDB::getInstance(); $db2 = MySQLDB::getInstance(); var_dump($db1, $db2);3,可以無(wú)限制的調(diào)用getInstance得到任意多個(gè)對(duì)象!但是此時(shí)得到對(duì)象都需要經(jīng)過(guò) getInstance,可以在getInstance內(nèi),增加限制,使用戶得到對(duì)象的改變!
在實(shí)例化好對(duì)象后,將對(duì)象存起來(lái),下次再執(zhí)行時(shí),判斷是否已經(jīng)有保存的,有了,直接返回已經(jīng)存在的,沒(méi)有,實(shí)例化后,保存起來(lái),再返回!
增加一個(gè)私有的靜態(tài)屬性,在 getinstance內(nèi)做判斷class MySQLDB { // 判斷是否實(shí)例化過(guò) public static $getinstance; // 私有化構(gòu)造函數(shù) private function __construct () { } // 執(zhí)行new public static function getInstance () { // 沒(méi)有實(shí)例化 if ( !(self::$getinstance instanceof self) ) { self::$getinstance = new self; } return self::$getinstance; } }4:還可以通過(guò)克隆來(lái)得到新對(duì)象
需要私有化__clone()方法// 私有化 __clone 方法 private function __clone () { }注意:?jiǎn)卫J絺鲄?wèn)題
在項(xiàng)目的設(shè)計(jì)層面解決單例的問(wèn)題
增加一個(gè)實(shí)例化的方法(函數(shù))
作用:用戶如果想要得到單例對(duì)象,就通過(guò)調(diào)用該函數(shù)完成!function getInstace ( $class_name ) { static $objects = array(); if ( !isset($objects[$class_name]) ) { $objects[$class_name] = new $class_name; } return $objects[$class_name]; }優(yōu)點(diǎn):靈活,可以針對(duì)多個(gè)類(lèi)同時(shí)實(shí)現(xiàn)單例,而且,類(lèi)還可以回歸到非單例的效果。
重載overload屬性重載 __set() __get()
傳統(tǒng)意義的重載,一個(gè)方法的多種狀態(tài),通常使用,參數(shù)類(lèi)型或者參數(shù)個(gè)數(shù)進(jìn)行區(qū)分,決定當(dāng)前使用那個(gè)函數(shù)。
PHP不支持同名方法。
PHP的重載:指的是對(duì)不可訪問(wèn)的成員的操作。
不可訪問(wèn)的成員: 指的是 不存在 , 或者是,由于訪問(wèn)修飾控制訪問(wèn)不到的。// PHP允許為對(duì)象增加類(lèi)中沒(méi)有定義的屬性 class Student { public $stu_name; private $stu_id; } $stu = new Student(); var_dump($stu); echo "
"; $stu->stu_gender = "male"; var_dump($stu);
// PHP對(duì)屬性除了增加,還支持刪除 class Student { public $stu_name; private $stu_id; } $stu = new Student(); $stu->stu_gender = "male"; unset($stu->stu_name); var_dump($stu);對(duì)類(lèi)后續(xù)進(jìn)行操作,用戶可以操作對(duì)象任意的修改對(duì)象的結(jié)構(gòu)。
PHP如何處理上面的情況,稱(chēng)之為重載(屬性的重新加載,成員的重新加載).重載:對(duì)成員的重新加載
成員分為:屬性和方法,因此,php支持屬性重載 和 方法重載.
屬性重載PHP對(duì),不可訪問(wèn)的屬性進(jìn)行操作處理方法,稱(chēng)之為屬性重載
PHP需要通過(guò)支持 魔術(shù)方法完成。
PHP在處理重載屬性時(shí),支持使用4個(gè)魔術(shù)方法,完成處理屬性重載的情況.__set()
當(dāng)為不可訪問(wèn)的屬性賦值時(shí),會(huì)被自動(dòng)調(diào)用
會(huì)得到兩個(gè)參數(shù),當(dāng)前操作的屬性名,和屬性值!// $p_name string 屬性名 // $p_value mixed 屬性值 public function __set ( $p_name, $p_value ) { // 實(shí)現(xiàn), 處理情況 return ; }典型的,__set()的作用, 用于嚴(yán)格控制對(duì)象結(jié)構(gòu),和批量處理可以被修改的屬性。
// $p_name string 屬性名 // $p_value mixed 屬性值 public function __set ( $p_name, $p_value ) { // 實(shí)現(xiàn), 處理情況 // 不可增加任何屬性, 但是可以對(duì) age 和 gender 做出修改 $allow_preperties = array("s_age", "s_gender"); if ( in_array($p_name, $allow_preperties) ) { $this->$p_name = $p_value; // 利用可變屬性,屬性名由變量代替 } } $s = new Student(); $s->s_name = "天機(jī)老人"; $s->s_age = 87;__get()
當(dāng)訪問(wèn)不可訪問(wèn)的屬性時(shí),會(huì)被自動(dòng)調(diào)用
需要的參數(shù)是:一個(gè),為當(dāng)前操作的屬性名public function __get ( $p_name ) { // 讀取名字 性別 if ( $p_name == "s_name" || $p_name == "s_gender" ) { return $this->$p_name; // 可變屬性 } else { // 讀取年齡 if ( $this->s_gender == "male" ) { return $this->s_age; } } }__unset()
在刪除一個(gè)不可訪問(wèn)的屬性時(shí),可以自動(dòng)被調(diào)用!
需要一個(gè)參數(shù) 當(dāng)前操作的屬性名。
此時(shí)就可以利用業(yè)務(wù)邏輯完成 屬性的刪除處理!public function __unset ( $p_name ) { if ( $cound ) { unset($this->$p_name); } }__isset()
在判斷一個(gè)不可訪問(wèn)的屬性是否存在時(shí),被自動(dòng)調(diào)用
需要一個(gè)參數(shù),屬性名
注意,次函數(shù)需要返回true,或者false,表示屬性是否存在public function __isset ( $p_name ) { if ( $p_name == "s_gender" ) { return true; } else { return false; } }方法重載__call()
當(dāng)訪問(wèn)一個(gè)不可訪問(wèn)的對(duì)象方法時(shí),會(huì)觸發(fā)__call()的魔術(shù)方法!
需要的參數(shù)時(shí):
2個(gè)參數(shù),第一是當(dāng)前的方法名,第二是調(diào)用時(shí)使用的實(shí)參列表!public function _call ( $m_name, $m_args ) { var_dump($m_name, $m_args); } $s = new Student(); $s->sayName("zf", "php");典型應(yīng)用
1,給出友好提示
2,執(zhí)行默認(rèn)操作public function _call ( $m_name, $m_args ) { var_dump($m_name, $m_args); echo "執(zhí)行了默認(rèn)操作"; $this->default_action(); } public function default_action () { echo "這里是操作"; } $s = new Student(); $s->sayName("zf", "php");static __callStatic()
與 __call類(lèi)似,當(dāng)靜態(tài)調(diào)用一個(gè)不可訪問(wèn)的方法時(shí),會(huì)自動(dòng)執(zhí)行!
public static function __callStatic ( $m_name, $m_args ) { var_dump( $m_name, $m_args ); } Student::sayCount();魔術(shù)方法
magic method在特定的情況下,會(huì)被自動(dòng)調(diào)用的方法,通常負(fù)責(zé)完成某塊獨(dú)立的功能的方法稱(chēng)之為魔術(shù)方法!
特點(diǎn):1,需要用戶腳本定義,不定義不執(zhí)行!2,命名方式都是以__開(kāi)頭__invoke()
將一個(gè)對(duì)象,當(dāng)作函數(shù)調(diào)用時(shí),會(huì)觸發(fā)該對(duì)象的__invoke()方法,由此方法,就可以調(diào)用,沒(méi)有該方法就不能調(diào)用!
__invoke是PHP實(shí)現(xiàn)匿名函數(shù) 不可或缺的部分!
也可以傳遞參數(shù),為對(duì)象傳遞參數(shù),就是為invoke魔術(shù)方法傳遞參數(shù)!
Closure 類(lèi)的對(duì)象(匿名函數(shù),閉包函數(shù)) 可以當(dāng)作函數(shù)調(diào)用,為什么我們自己定義的對(duì)象不可以當(dāng)做函數(shù)調(diào)用? 內(nèi)置的Closure 類(lèi)中有 __invoke();方法.
在將一個(gè)對(duì)象當(dāng)做函數(shù)調(diào)用時(shí), 會(huì)觸發(fā)該對(duì)象的 __invoke 方法, 如果方法不存在,對(duì)象不能當(dāng)做函數(shù)調(diào)用。反之 如果需要調(diào)用這個(gè)對(duì)象, 則可以為該對(duì)象增加 __invoke 方法使之執(zhí)行.
調(diào)用對(duì)象,其實(shí)就是調(diào)用該方法,可以接受參數(shù)!普通方法一樣處理即可.
魔術(shù)方法,只會(huì)負(fù)責(zé)某個(gè)特定的功能。當(dāng)某個(gè)特別的情況發(fā)生時(shí),才會(huì)調(diào)用相應(yīng)的魔術(shù)方法。
魔術(shù)方法可以沒(méi)有, 一旦有的話就會(huì)被調(diào)用.__toString()
轉(zhuǎn)換到字符串的意思!
當(dāng)將對(duì)象當(dāng)作字符串使用時(shí),會(huì)自動(dòng)調(diào)用該對(duì)象的魔術(shù)方法!存在toString 魔術(shù)方法,即可以完成轉(zhuǎn)換。
靜態(tài)延遲綁定
toString的返回值,就是轉(zhuǎn)換的結(jié)果,一般轉(zhuǎn)換對(duì)象的標(biāo)志性的屬性即可!$this永遠(yuǎn)代表所在類(lèi)的對(duì)象?
不是
$this的值取決于$this所在方法的執(zhí)行對(duì)象環(huán)境.self用于代表所在類(lèi)么?
是,永遠(yuǎn)代表所在類(lèi)的對(duì)象!
self 永遠(yuǎn)表示所在的類(lèi).
在那個(gè)類(lèi)中被定義,就應(yīng)該表示那個(gè)類(lèi).
因?yàn)閟elf,parent關(guān)鍵字,類(lèi)的編譯階段就確定了所代表的類(lèi).class P { public static $where = "P static,
"; public static function sayWhere () { echo self::$where; } } class C extends P { public static $where = "C static"; } echo P::sayWhere(); // P static, echo C::sayWhere(); // P static,此時(shí),應(yīng)該是表示當(dāng)前類(lèi)的關(guān)鍵字,最好應(yīng)該在調(diào)用時(shí)決定最好!(self不能做到)
此時(shí),采用一個(gè)新的關(guān)鍵字,代表當(dāng)前類(lèi),與self不同,在于是 運(yùn)行時(shí)調(diào)用時(shí)決定,而不是在類(lèi)編譯時(shí)就確定好了的!
使用關(guān)鍵字:staticclass P { public static $where = "P static,
"; public static function sayWhere () { echo self::$where; } public static function sayW () { echo static::$where; } } class C extends P { public static $where = "C static,"; } echo P::sayWhere(); // P static, echo C::sayWhere(); // P static, echo "
"; echo P::sayW(); // P static, echo C::sayW(); // C static,static關(guān)鍵字的功能
聲明靜態(tài)局部變量
聲明靜態(tài)成員
當(dāng)前類(lèi),運(yùn)行的當(dāng)前類(lèi)類(lèi)中,可以表示類(lèi)的關(guān)鍵字:
反射機(jī)制
self, 所在類(lèi)
static,調(diào)用類(lèi)
parent, 父類(lèi)常見(jiàn)的類(lèi)和對(duì)象操作函數(shù):
instanceof,判斷對(duì)象是否是某個(gè)類(lèi)的實(shí)例。 get_class(); // 返回對(duì)象的類(lèi)名 class_exists(); // 判斷一個(gè)類(lèi)是否存在 get_declared_classer() // 獲得當(dāng)前已經(jīng)存在的類(lèi). 包括預(yù)定義和用戶自定義的。 method_exists(); property_exists();相應(yīng)的魔術(shù)常量
__CLASS__ , 當(dāng)前類(lèi)名
__METHOD__, 當(dāng)前方法名get_class_methods(); // 得到類(lèi)的方法
get_class_vars(); // 得到類(lèi)的屬性
可以得到類(lèi)內(nèi)的方法和屬性。
但是,得到的信息較少,只有名字,而且受到訪問(wèn)修飾符的限制。
如何才能夠詳細(xì)精確到類(lèi)中的結(jié)構(gòu)?
使用到反射機(jī)制PHP提供的,用于獲得某個(gè)類(lèi),或者某種結(jié)構(gòu)(類(lèi),函數(shù),方法,屬性,參數(shù),擴(kuò)展....);
需要使用反射機(jī)制,反射機(jī)制時(shí)利用OOP的語(yǔ)法實(shí)現(xiàn)了。
反射機(jī)制提供了很多類(lèi),針對(duì)不同的結(jié)構(gòu),會(huì)使用到不同的反射類(lèi)對(duì)象。
reflection: 反射類(lèi). 可以通過(guò)對(duì)象反過(guò)來(lái)獲得對(duì)象的相關(guān)信息.如果需要知道某個(gè)類(lèi)的結(jié)構(gòu),就應(yīng)該使用refletionClass
存在一個(gè)靜態(tài)方法,refletionClass::export() 可以導(dǎo)出一個(gè)類(lèi)的結(jié)構(gòu)報(bào)告反射機(jī)制可以獲得目標(biāo)結(jié)構(gòu)的內(nèi)部結(jié)構(gòu)。
并同時(shí)可以驅(qū)動(dòng)目標(biāo)結(jié)構(gòu)運(yùn)行起來(lái).(代理執(zhí)行);name, "類(lèi)型約束
"; } public function tan($c1, $c2) { echo "
" . $c1 . " ". $c2; } } $p = new Persion(); // $p->say(); // 利用反射對(duì)象調(diào)用方法 $method = new ReflectionMethod("Persion", "say"); // 反射方法對(duì)象 $method->invoke($p); $method2 = new ReflectionMethod("Persion", "tan"); //參數(shù)的反射方法 $method2->invokeArgs($p, array("pink", "red")); ?>約束函數(shù),或者方法類(lèi)參數(shù)的類(lèi)型,只能是某個(gè)類(lèi)的對(duì)象。
PHP是弱類(lèi)型,變量可以存儲(chǔ)任意類(lèi)型的數(shù)據(jù)
函數(shù),方法的參數(shù)也是可以接受任意類(lèi)型但是參數(shù),可以被規(guī)定為,某個(gè)類(lèi)的固定對(duì)象,在參數(shù)前增加類(lèi)名即可。
function sayName ( Student $o ) { echo $o->stu_name; } sayName("php");支持類(lèi)名,和數(shù)組。其它數(shù)據(jù)類(lèi)型不支持。
function sayName ( Array $arr ) { }對(duì)象的遍歷對(duì)象是一個(gè)集合數(shù)據(jù)類(lèi)型
foreach遍歷
遍歷對(duì)象,是依次獲得對(duì)象擁有的屬性的信息(注意,訪問(wèn)修飾符的限制)class Student { public $stu_name; public $stu_age; public $stu_gender; } $obj = new Student(); $obj->stu_name = "李尋歡"; $obj->stu_age = 30; $obj->stu_gender = "male"; foreach ( $obj as $val => $key ) { var_dump($val,$key); echo "
"; }自定義遍歷,iterator
iterator迭代器接口Iterator接口,PHP預(yù)定義完成。
實(shí)現(xiàn)Iterator接口// 類(lèi)實(shí)現(xiàn)Iterator 接口 class Team implements Iterator { public function rewind () { reset($this->stu_infos); } public function valid () { return key($this->stu_infos) !== null; } public function current () { return current($this->stu_infos); } public function key () { return key($this->stu_infos); } public function next () { next($this->stu_infos); } }魔術(shù)常量
__CLASS__:當(dāng)前類(lèi)名。注意:可以new self 不可以 new __CLASS__
__METHOD__,當(dāng)前方法名。區(qū)別__FUNCTION__
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/21756.html
摘要:很多情況下,通常一個(gè)人類(lèi),即創(chuàng)建了一個(gè)具體的對(duì)象。對(duì)象就是數(shù)據(jù),對(duì)象本身不包含方法。類(lèi)是相似對(duì)象的描述,稱(chēng)為類(lèi)的定義,是該類(lèi)對(duì)象的藍(lán)圖或原型。在中,對(duì)象通過(guò)對(duì)類(lèi)的實(shí)體化形成的對(duì)象。一類(lèi)的對(duì)象抽取出來(lái)。注意中,對(duì)象一定是通過(guò)類(lèi)的實(shí)例化來(lái)的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...
摘要:很多情況下,通常一個(gè)人類(lèi),即創(chuàng)建了一個(gè)具體的對(duì)象。對(duì)象就是數(shù)據(jù),對(duì)象本身不包含方法。類(lèi)是相似對(duì)象的描述,稱(chēng)為類(lèi)的定義,是該類(lèi)對(duì)象的藍(lán)圖或原型。在中,對(duì)象通過(guò)對(duì)類(lèi)的實(shí)體化形成的對(duì)象。一類(lèi)的對(duì)象抽取出來(lái)。注意中,對(duì)象一定是通過(guò)類(lèi)的實(shí)例化來(lái)的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...
摘要:很多情況下,通常一個(gè)人類(lèi),即創(chuàng)建了一個(gè)具體的對(duì)象。對(duì)象就是數(shù)據(jù),對(duì)象本身不包含方法。類(lèi)是相似對(duì)象的描述,稱(chēng)為類(lèi)的定義,是該類(lèi)對(duì)象的藍(lán)圖或原型。在中,對(duì)象通過(guò)對(duì)類(lèi)的實(shí)體化形成的對(duì)象。一類(lèi)的對(duì)象抽取出來(lái)。注意中,對(duì)象一定是通過(guò)類(lèi)的實(shí)例化來(lái)的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...
閱讀 3498·2021-11-25 09:43
閱讀 2665·2021-09-22 15:54
閱讀 623·2019-08-30 15:55
閱讀 1004·2019-08-30 15:55
閱讀 2028·2019-08-30 15:55
閱讀 1770·2019-08-30 15:53
閱讀 3495·2019-08-30 15:52
閱讀 2066·2019-08-30 12:55