這裡所說的PHP物件導向,準確的說應該叫做PHP物件導向編程,php物件導向編程的三個基本特徵分別為封裝、繼承和多態,下面我們就來分別看看PHP物件導向的三大特徵。
一、php物件導向三大特徵:
1、封裝:
封裝就是把抽象出的資料和對資料的操作封裝在一起,資料被保護在內部,程式的其他部分只有通過被授權的操作(成員方法)才能對資料進行操作。
存取控制符賦值取值.png
2、繼承:
所謂繼承,就是一個子類通過extends 父類 把父類的一些(public / protected)屬性和(public / protected)方法繼承下來。不能繼承私人的。
作用:增加代碼複用性,管理代碼成本低。 基本文法: class 類名 extends 父類名 { //需要的非私人屬性和方法 }
繼承.png
<?php //父類 Class Student { public $name; protected $age; protected $grade; // public __construct() { // } public function showInfo() { echo $this -> name."<br/>".$this -> age; } } /** * 小學生 */ class Pupil extends Student { public function test() { echo "<br/>小學生在考試。。。"; } } /** * 大學生 */ class Graduate extends Student { public function test() { echo "<br/>大學生在考試。。。"; } } $stu1 = new Pupil(); $stu1 -> name = "lizzy"; $stu1 -> test(); $stu1 -> showInfo(); $stu2 = new Graduate(); $stu2 -> name = "zxm"; $stu2 -> test(); $stu2 -> showInfo();?>
注意:
(1)protected屬性和方法受保護,在子類不能直接調用,要在子類中定義方法訪問。
Class ParentClass { public $name = 'lizzy'; protected $age = 24; private $sex = "女"; public function test1() { echo "<br/>展示public方法"; } protected function test2() { echo "<br/>展示protected方法"; } private function test3() { echo "<br/>展示private方法"; }}Class SubClass extends ParentClass { function show() { echo "age=".$this->age; // echo "sex=".$this->sex;//是不能繼承下來的 $this -> test2(); }}$sub1 = new SubClass();$sub1 -> show();$sub1 -> test1();
(2)如果希望子類調用父類的構造方法,或者其他方法(public / protected),可以使用類名::方法名; 或者parent::方法名;
Class A { public $n1=90; public function __construct() { echo "A的構造方法"; }}Class B extends A { function __construct() { echo "B的構造方法"; //調用父類的兩種方法 // A::__construct(); parent::__construct(); }}$b = new B();
(3)當一個子類的方法和父類方法(protected/public)完全一致時,我們稱之為方法的覆蓋(重寫)。
3、多態:
“重載”是類的多態的一種表現;
重載的概念:函數名一樣,通過函數的參數個數或者參數類型不同,達到調用同一個函數名,但是可以區分不同的函數。
魔法函數__call,但不推薦使用; 它一個對象調用某個方法,而該方法不存在,則系統會自動調用__call。
<?php Class A { public function test1($p) { echo "接收一個參數<br/>"; } public function test2($p) { echo "接收兩個參數<br/>"; } //提供__call 它一個對象調用某個方法,而該方法不存在,則系統會自動調用__call function __call($method,$p) { if ($method == "test") { if (count($p) == 1) { $this -> test1($p); } elseif (count($p) == 2) { $this -> test2($p); } } } } $a = new A(); $a -> test(1); $a -> test(21,43)?>
常見魔法常量:兩個底線LINE兩個底線;當前多少行;
兩個底線FILE兩個底線;當前檔案的絕對路徑;
方法的重寫/覆蓋(override):
1、當一個父類知道所有的子類都有一個方法,但是父類不能確定該方法究竟如何寫,可以讓子類去覆蓋這個方法。
使用如下:
<?php Class Animal { function cry() { echo "不知道怎麼叫"; } } //重寫 Class Dog extends Animal { function cry() { echo "小狗汪汪叫"; } } //重寫 Class Pig extends Animal { function cry() { echo "小豬哼哼叫"; } } $dog = new Dog(); $dog -> cry(); $pig = new Pig(); $pig -> cry();?>
方法重寫的細節:
1、重寫子類的函數名和參數個數必須和父類的一致;但不要求參數的名稱一樣。
2、如果子類要去調用父類的某個方法(public / protected)可以使用parent::方法名(); 或者父類名::方法名(); 可根據情況是否傳參。
3、實現方法覆蓋時,存取修飾詞可以不一樣,但是必須滿足子類的存取範圍>=父類的存取範圍。
多態體現的地方:
當子類沒有覆蓋父類的方法,則子類調用的是父類,當子類覆蓋了父類的方法則調用的是自己的方法。