一、物件導向基礎 |
1、什麼是類?
具有相同屬性(特徵)和方法(行為)的一系列個體的集合,類別是抽象的概念。
2、什麼是物件?
從類別中,得到的具有具體屬性值的個體,稱為物件。對像是一個具體的個體。
eg:人類;張三
3、類別和物件的關係?
類別是物件的抽象化!對像是類別的具體化!
類別只是表示這類物件有哪些屬性,但是不能有具體的值,所以類別是抽象的。
物件是將類別的所有屬性賦值後,產生具體的個體,所有物件是具體的。
##1、如何宣告一個類別:
class 類別名稱{
存取修飾符 $屬性[=預設值];
[存取修飾符] function 方法(){}
}
2、宣告一個類別的注意事項:
①類別名稱只能有字母數字底線組成,開頭不能是數字,必須符合大駝峰法則;
②類別名稱必須使用class修飾,類別名稱後面一定不能有();
③屬性必須要帶存取修飾符,方法可以不帶存取修飾符。
3、實例化物件及物件屬性方法的呼叫:
$物件名稱 = new 類別名稱(); //()可以不帶
類別外部呼叫屬性與方法:
$物件名稱-> $屬性名稱; //使用->呼叫屬性時,屬性名稱不能帶$符號
類別內部呼叫屬性與方法:
$this -> $屬性名;
#1、什麼是建構子?
建構子是類別中的一個特殊函數,當我們使用new關鍵字實例化物件時,相當於呼叫了類別的建構子。
2、建構子有什麼作用?
實例化物件時,自動調用,用於給物件的屬性賦初值!
3、建構子的寫法:
①建構函式名,必須與類別同名
[public] function Person($name){
$this -> name = $name;
#}
②使用魔術方法__construct
[public] function __construct($name){
# $this -> name = $name;
##}
4、建構子注意事項:
①第一種寫法,建構函式名稱必須與類別同名! ! ! !
②如果一個類別沒有手寫建構函數,則系統預設會有一個空參構造,因此可以使用new Person();
如果我們寫了帶參數的建構函數,則不會再有空參構造,也就是不能直接使用new Person();
Person後面的()中的參數列表,必須符合建構子的要求! ! ! !
③如果兩種建構子同時存在,將使用__construct。
5、析構函數:__destruct():
#①析構函數在物件被銷毀釋放之前自動呼叫;
②析構函數不能帶有任何的參數;
③析構函數常用於物件使用完以後,釋放資源,關閉資源等。
6、魔術方法:
PHP中,提供我們一系列以__開頭的函數,這些函數不需要自己手動調用,
會在適當的時機自動調用,這類函數稱為魔術稱為魔術函數。
eg:function __construct(){} 在類別new一個物件時自動呼叫
function __destruct(){} 在物件被銷毀時自動呼叫
我們要求,除了魔術方法之外,自訂的函數與方法不能使用__開頭。
最後,一般對於功能比較複雜的類,我們會單獨的寫到一個類別文件中。
類別檔案的命名,同一小寫,使用"類別名稱小寫.class.php"的方式命名。
在其他檔案中使用這個類別時,可以使用include導入這個".class.php"檔案。
#
二、封裝與繼承 |
1、什麼是封裝?
透過存取修飾符,將類別中不需要外部存取的屬性和方法進行私有化處理,以實現存取控制。
*注意:是實現存取控制,而不是拒絕存取。也就是說,我們私有化屬性後,需要提供對應的方法,讓使用者透過我們提供的方法處理屬性。
2、封裝的作用?
①使用者只關心類別能夠提供的功能,不關心功能實現的細節! (封裝方法)
②對使用者的資料進行控制,防止設定不合法數據,控制傳回給使用者的資料(屬性封裝+set/get方法)
3、實作封裝作業?
①方法的封裝
對於一些只在類別內部使用的方法,而不是像對外部提供使用,那麼,這樣的方法我們可以使用private進行私有化處理。
private function formatName(){} //这个方法仅仅能在类内部使用$this调用 function showName(){ $this -> formatName(); }
②屬性的封裝+set/get方法
為了控制屬性的設定以及讀取,可以將屬性進行私有化處理,並要求使用者透過我們提供的set/get方法進行設定
private $age; //set方法 function setAge($age){ $this->age=$age; } //get方法 function getAge(){ return $this->age; }
$物件->getAge() ;
$物件->setAge(12);
#③屬性的封裝+魔術方法
private $age; function __get($key){ return $this->$key; } function __set($key,$value){ $this->$key=$value; }
$物件->age; //存取物件私有屬性時,自動呼叫__get()魔術方法,並且將存取的屬性名稱傳給__get()方法;
$物件->age=12; //設定物件私有屬性時,自動呼叫__set()魔術方法,並且將設定的屬性名稱以及屬性值傳給__set()方法;
注意:在魔術方法中,可以使用分支結構,判斷$key的不同,進行不同操作。
4、關於封裝的魔術方法:
①__set($key,$value):給類別私有屬性賦值時自動調用,調用時給方法傳遞兩個參數:需要設定的屬性名,屬性值。
②__get($key,$value):讀取類別私有屬性時自動調用,呼叫時給方法傳遞一個參數,需要讀取的屬性名稱;
③__isset($key):外部使用isset()函數偵測私有屬性時,自動呼叫。
>>>類別外部使用isset();偵測私有屬性,預設是偵測不到的。 false
>>>所以,我們可以使用__isset();函數,在自動呼叫時,回傳內部偵測結果。
function __isset($key){ return isset($this -> $key); }
當外部使用isset($物件名稱->私有屬性);偵測時,將自動呼叫上述__isset()傳回的結果!
④__unset($key):外部使用unset()函數刪除私有屬性時,自動呼叫;
1 function __unset($key){ #2 unset($this -> $key); 3 }
當外部使用unset($物件名稱->私有屬性);刪除屬性時,自動將屬性名稱傳給__unset(),並交由這個魔術方法處理。
1、如何实现继承?
给子类使用extends关键字,让子类继承父类;
class Student extends Person{}
2、实现继承的注意事项?
①子类只能继承父类的非私有属性。
②子类继承父类后,相当于将父类的属性和方法copy到子类,可以直接使用$this调用。
③PHP只能单继承,不支持一个类继承多个类。但是一个类进行多层继承。
class Person{}
class Adult extends Person{}
class Student extends Adult{}
//Student 类就同时具有了Adult类和Person类的属性和方法
3、方法覆盖(方法重写)
条件一: 子类继承父类
条件二:子类重写父类已有方法
符合上述两个条件,称为方法覆盖。覆盖之后,子类调用方法,将调用子类自己的方法。
同样,除了方法覆盖,子类也可以具有与父类同名的属性,进行属性覆盖。
如果,子类重写了父类方法,如何在子类中调用父类同名方法?
partent::方法名();
所以,当子类继承父类时,需在子类的构造中的第一步,首先调用父类构造进行复制。
function __construct($name,$sex,$school){ partent::__construct($name,$sex); $this -> school = $school; }
三、PHP关键字 |
1、final
①final修饰类,此类为最终类,不能被继承!
②final修饰方法,此方法为最终方法,不能被重写!
③final不能修饰属性。
2、static
①可以修饰属性和方法,分别称为静态属性和静态方法,也叫类属性,类方法;
②静态属性,静态方法,只能使用类名直接调用。
使用"类名::$静态属性" , "类名::静态方法()"
Person::$sex; Person::say();
③静态属性和方法,在类装载时就会声明,先于对象产生。
④静态方法中,不能调用非静态属性或方法;
非静态方法,可以调用静态属性和方法。
(因为静态属性和方法在类装载时已经产生,而非静态的属性方法,此时还没有实例化诞生)
⑤在类中,可以使用self关键字,代指本类名。
class Person{ static $sex = "nan"; function say(){ echo self::$sex; } }
⑥静态属性是共享的,也就是new出很多对象,也是共用一个属性。
3、const关键字:
在类中声明常量,不能是define()函数!必须使用const关键字。
与define()声明相似,const关键字声明常量不能带$,必须全部大写!
常量一旦声明,不能改变。调用时与static一样,使用类名调用Person::常量。
4、instanceof操作符:
检测一个对象,是否是某一个类的实例。(包括爹辈,爷爷辈,太爷爷辈……)
$zhangsan instanceof Person;
① . 只能连接字符串; "".""
② => 声明数组时,关联键与值["key"=>"value"]
③ -> 对象($this new出的对象)调用成员属性,成员方法;
④ :: ①使用parent关键字,调用父类中的同名方法:parent::say();
②使用类名(和self)调用类中的静态属性,静态方法,以及常量。
四、单例 |
單例模式也稱為單態模式。可以保證,一個類別只能有一個物件實例。
實作重點:
①建構函式私有化,不允許使用new關鍵字建立物件。
②對外提供取得物件的方法,在方法中判斷物件是否為空。
若為空,則建立物件並傳回;如果不為空則直接傳回。
③實例物件的屬性以及取得物件的方法必須都是靜態的。
④之後,建立物件只能使用我們提供的靜態方法。
eg:$s1 = Singleton::getSingle();
#
五、物件串列化和魔術方法 |
***关键词:clone与__clone、__antoload()、串行化与反串行化(序列化与反序列化)、类型约束、魔术方法小总结(12个)
1、当使用=讲一个对象,赋值给另一个对象时,赋的实际是对象的地址。
两个对象指向同一地址,所以一个对象改变,另一个也会变化。
eg: $lisi = $zhangsan;
2、如果想要将一个对象完全克隆出另一个对象,两个对象是独立的,互不干扰的,
则需要使用clone关键字;
eg: $lisi = clone $zhangsan; //两个对象互不干扰
3、__clone():
①当使用clone关键字,克隆对象时,自动调用clone函数。
②__clone()函数,类似于克隆时使用的构造函数,可以给新克隆对象赋初值。
③__clone()函数里面的$this指的是新克隆的对象
某些版本中,可以用$that代指被克隆对象,绝大多数版本不支持。
4、__toString()
当使用echo等输出语句,直接打印对象时调用echo $zhangsan;
那么,可以指定__toString()函数返回的字符串;
function __toString(){ return "haha"; } echo $zhangsan; //结果为:haha
5、__call()
调用类中未定义或未公开的方法时,会自动执行__call()方法。
自动执行时,会给__call()方法传递两个参数;
参数一:调用的方法名
参数二:(数组)调用方法的参数列表。
①这是唯一一个不在类中使用的魔术方法;
②当实例化一个不存在的类时,自动调用这个魔术方法;
③调用时,会自动给__autoload()传递一个参数:实例化的类名
所以可以使用这个方法实现自动加载文件的功能。
function __autoload($className){ include "class/".strtolower($className).".class.php"; } $zhangsan=new Person();//本文件内没有Person类,会自动执行__autoload()加载person.class.php文件
1、串列化:將物件經過一系列操作,轉換為字串的過程,稱為串列化。
(物件透過寫出描述自己狀態的數值來記錄自己)
#2、反串列化:將串列化後的字串,再轉為物件的過程,稱為反串列化;
3、什麼時候使用串列化?
①物件需要在網路中傳輸的時候
② 物件需要在檔案或資料庫中持久保存的時候
4、如何實現串行化與反串行化
串行化: $str=serialize($zhangsan);
反串行化:$duixiang=unserialize ($str);
5、__sleep()魔術方法:
①當執行物件串列化的時候,會自動執行__sleep()函數;
②__sleep()函數要求回傳一個數組,數組中的值,就是可以串行化的屬性;不在數組中的屬性,不能被串行化;
#function __sleep(){
return array("name","age"); //只有name/age兩個屬性可以串列化。
}
6、__wakeup()魔術方法
①當反串列化物件時,自動呼叫_ _wakeup()方法;
②自動呼叫時,用於給反串行化產生的新物件屬性,進行重新賦值。
1 function __wakeup(){ 2 $this -> ; name = "李四"; 3 }
1、類型限制:是指在變數時,加上資料類型,用於約束此變數只能存放對應的資料型態。
(這個運算常見於強型別語言,在PHP中,只能實作陣列與物件的型別限制)
2、如果類型約束為某一個類,則本類以及本類的子類對象,都可以通過。
3、在PHP中,型別約束,只能發生在函數的形參中。
class Person{} class Student extends Person{} function func(Person $p){ //约束函数的形参,只接受Person类及Person子类 echo "1111"; echo $p -> name; }
func(new Person()); √
func(new Student()); √
func("111"); ×
形如new Person();的形式,我们称其为"匿名对象";
※※※基类:父类
※※※派生类:子类
1、__construct():构造函数,new一个对象时,自动调用。
2、__destruct():析构函数,当一个对象被销毁前,自动调用。
3、__get():访问类中私有属性时,自动调用。传递读取的属性名,返回$this->属性名
4、__set():给类的私有属性赋值时,自动调用。传递需要设置的属性名和属性值;
5、__isset():使用isset()检测对象私有属性时,自动调用。传递检测的属性名,返回isset($this -> 属性名);
6、__unset():使用unset()删除对象私有属性时,自动调用。传递删除的属性名,方法中执行unset($this -> 属性名);
7、__toString():使用echo打印对象时,自动调用。返回想要在打印对象时,显示的内容;返回必须是字符串;
8、__call():调用一个类中未定义或未公开的方法时,自动调用。传递被调用的函数名,和参数列表数组;
9、__clone():当使用clone关键字,克隆一个对象时,自动调用。作用是为新克隆的对象进行初始化赋值;
10、__sleep():对象序列化时,自动调用。返回一个数组,数组中的值就是可以序列化的属性;
11、__wakeup():对象反序列化时,自动调用。为反序列化新产生的对象,进行初始化赋值;
12、__autoload():需要在类外部声明函数。当实例化一个未声明的类时,自动调用。传递实例化的类名,可以使用类名自动加载对应的类文件。
六、抽象类和抽象方法 |
1、什麼是抽象方法?
沒有方法體{}的方法,必須使用abstract關鍵字修飾。這樣的方法,我們稱為抽象方法。
abstract function say(); //抽象方法
#2、什麼是抽象類別?
使用abstract關鍵字修飾的類別就是抽象類別。
abstract class Person{}
3、抽象類別的注意事項:
① 抽象類別可以包含非抽象方法;
② 包含抽象方法的類別必須是抽象類,抽象類別不一定必須包含抽象方法;
③ 抽象類,不能實例化。 (抽象類別中可能包含抽象方法,抽象方法沒有方法體,實例化呼叫沒有意義)
我們使用抽象類別的目的,就是限制實例化! ! !
4、子類別繼承抽象類,那麼子類別必須重寫父類別的所有抽象方法,除非,子類別也是抽象類別。
5、使用抽象類別的作用?
① 限制實例化。 (抽象類別是不完整的類,裡面的抽象方法沒有方法體,所以不能實例化)
② 抽象類別為子類別的繼承提供一個規範,子類別繼承一個抽象類,則必須包含並且實作抽象類別中已定的抽象方法。
#七、介面與多態 |
#1、什麼是接口?
介面是一種規範,提供了一組實作介面的類別所必須實現的方法組合。
介面使用interface關鍵字宣告;
interface Inter{}
2、接口中的所有方法,必須都是抽象方法。
介面中的抽象方法不需要也不能使用abstract修飾。
3、介面中不能宣告變量,不能有屬性,只能使用常數! ! !
4、介面可以繼承接口,使用extends關鍵字!
介面使用extends繼承接口,可以實現多重繼承。
interface int1 extends Inter,Inter2{}
#5、類別可以實作接口,使用implements關鍵字!
類別使用implements實作接口,可同時實作多個接口,多個接口間逗號分隔;
abstract class Person implements Inter,Inter2{}
#一個類別實作一個或多個接口,那麼這個類,必須實作所有接口中的所有抽象方法!
除非,這個類別是抽象類別。
①宣告方式上,介面使用interface關鍵字,抽象類別使用abstract class。
②實作/繼承方式上,一個類別使用extends繼承抽象類,使用implements實作介面。
③抽象類別只能單繼承,介面可以多實作。 (介面extends介面)、多重實作(類別implements介面)
④抽象類別中可以有非抽象方法,介面中只能有抽象方法,不能有費抽象方法。抽象類別中的抽象方法必須使用abstract關鍵字修飾,介面中抽象方法不能帶修飾詞。
⑤抽象類別是個類,可以有屬性、變數;介面中只能有常數。
##二、多態
2、實作多態的必要途徑:
① 子類別繼承父類別;
② 子類別重寫父類別方法;
③ 父類別引用指向子類別物件
########################################################################################################################### ## ###
以上是PHP物件導向實用基礎知識的詳細內容。更多資訊請關注PHP中文網其他相關文章!