PHP5&MySQL 程式設計 第 6 章物件導向
6-1 認識物件導向 物件 (object) 或 案例 (instance) 屬性 (property) 欄位 (field) 或 成員變數 (member variable) 方法 (method) 或 成員函式 (member function) 事件 (event) 類別 (class)
物件導向程式設計 (OOP) 具有下列特點 : 封裝 (encapsulation) 繼承 (inheritance) 介面 (interface) 多型 (polymorphism)
6-2 定義類別 PHP 的類別可以包含下列成員 : 一 屬性 ( 又稱為欄位 成員變數 ) 二 方法 ( 又稱為成員函式 ) 三 常數四 建構函式 (constructor) 五 解構函式 (destructor)
class class_name [extends parentclass_name] [public private protected public private protected varvar $property_name [= value];] [[public private protected public private protected] function method_name name( ) ) ] [ ] var $MyName = ' 小丸子 '; class MyClass var $MyName = ' 小丸子 '; function Display() echo $this->myname MyName;
6-2-1 建立類別的物件 \ch06\prac06-1.php <HTML> <BODY> <?php class MyClass var $MyName = ' 小丸子 '; function Display() echo $this->myname MyName; $MyObject = new MyClass(); $MyObject->MyNameMyName = ' 花輪 '; $MyObject->Display();?> </BODY> </HTML>
\ch06\prac06-2.php 01:<HTML> 02: <BODY> 03: <?php 04: class MyClass 05: 06: function Display() 07: 08: echo ' 不用建立物件就可以呼叫方法喔!';! 09: 10: 11: MyClass::Display(); 12:?> 13: </BODY> 14:</HTML>
\ch06\prac06-3.php 01:<HTML> 02: <BODY> 03: <?php 04: class MyClass 05: 06: const PI = 3.14156; 07: function Display() 08: 09: echo MyClass::PI; 10: 11: 12: echo MyClass::PI.'<BR>'; 13: MyClass::Display(); 14:?> 15: </BODY> 16:</HTML> 6-2-2 常數
\ch06\prac06-4.php 01:<HTML> 02: <BODY> 03: <?php 04: class MyClass 05: 06: var $Message; 07: function construct construct($msg) 08: 09: $this->message = $Msg$ Msg; 6-2-3 建構函式 10: 11: function Display() 12: 13: echo $this->message; 14: 15: 16: $MyObject$ = new MyClass('Hello World!'); 17: $MyObject$ MyObject->Display(); 18:?> 19: </BODY> 20:</HTML>
6-2-4 解構函式 \ch06\prac06-5.php ( 下頁續 ) 01:<HTML> 02: <BODY> 03: <?php 04: class MyClass 05: 06: var $Message; 07: function construct($msg construct($msg) 08: 09: $this->message = $Msg$ Msg; 10: 11: function Display() 12: 13: echo $this->message; 14:
\ch06\prac06-5.php ( 接上頁 ) 14: function destruct() 15: 16: $this->message = NULL; 17: echo ' 這個物件即將被摧毀!';! 18: 19: 20: $MyObject$ = new MyClass('Hello World!'); 21: $MyObject$ = NULL; 22:?> 23: </BODY> 24:</HTML>
6-3 繼承 父類別 特徵 1 特徵 2 特徵 3 子類別 箭頭表示繼承自 特徵 1 特徵 2 定義於父類別, 但可以從子類別存取 特徵 3 特徵 4 定義於子類別
6-3-1 定義子類別 class childclass_name extends parentclass_name [ ]
\ch06\prac06-7.php <HTML> <BODY> <?php class A //... class B extends A //... class C extends B //...?> </BODY> </HTML> 類別 A 類別 B 類別 C 箭頭表示繼承自 箭頭表示繼承自
ch06\prac06 prac06-8.php <HTML> <BODY> <?php class W //... class X extends W //... class Y extends W //... class Z extends W //...?> </BODY> </HTML> 類別 X 類別 W 類別 Y 箭頭表示繼承自 類別 Z
6-3-2 設定成員的存取範圍 public private protected
\ch06\prac06-9.php 01:<HTML> 02: <BODY> 03: <?php 04: class ParentClass // 定義父類別 05: 06: public $Field1; // 定義 public 屬性 ( 能夠被繼承 ) 07: private $Field2; // 定義 private 屬性 ( 不能被繼承 ) 08: protected $Field3; // 定義 protected 屬性 ( 能夠被繼承 ) 09: public function Method1() // 定義 public 方法 ( 能夠被繼承 ) 10: private function Method2() // 定義 private 方法 ( 不能被繼承 ) 11: protected function Method3() // 定義 protected 方法 ( 能夠被繼承 ) 12: 13: 14: class ChildClass extends ParentClass // 定義子類別 15: 16: public $Field4; // 定義 public 屬性 ( 能夠被繼承 ) 17: private $Field5; // 定義 private 屬性 ( 不能被繼承 ) 18: protected $Field6; // 定義 protected 屬性 ( 能夠被繼承 ) 19: public function Method4() // 定義 public 方法 ( 能夠被繼承 ) 20: private function Method5() // 定義 private 方法 ( 不能被繼承 ) 21: protected function Method6() // 定義 protected 方法 ( 能夠被繼承 ) 22: 23:?> 24: </BODY> 25:</HTML>
6-3-3 覆蓋繼承自父類別的方法 \ch06\prac06-10.php ( 下頁續 ) 01:<HTML> 02: <BODY> 03: <?php 04: class Payroll // 定義父類別 05: 06: public $EmpName$ EmpName; // 定義屬性 ( 能夠被繼承 ) 07: public function Payment($Hours,, $PayRate$ PayRate) // 定義方法 ( 能夠被繼承 ) 08: 09: return $Hours * $PayRate$ PayRate; 10: 11:
12: class BonusPayroll extends Payroll // 定義子類別 13: 14: public function Payment($Hours,, $PayRate$ PayRate,, $Bonus)// 覆蓋父類別的方法 15: 16: return $Hours * $PayRate$ + $Bonus; 17: 18: 19: echo ' 尚未加上獎金的薪資為 '.Payroll::Payment(100, 80).'<BR>'; 20: echo ' 加上獎金之後的薪資為 '.BonusPayroll::Payment(100, 80, 500).'<BR>'; 21:?> 22: </BODY> 23:</HTML>
6-3-4 呼叫父類別內被覆蓋的方法 public function Payment($Hours,, $PayRate$ PayRate,, $Bonus) return $Hours * $PayRate$ + $Bonus; public function Payment($Hours,, $PayRate$ PayRate,, $Bonus) return parent::payment($hours,, $PayRate$ PayRate) + $Bonus; public function Payment($Hours,, $PayRate$ PayRate,, $Bonus) return Payroll::Payment($Hours,, $PayRate$ PayRate) + $Bonus;
6-3-5 抽象方法 \ch06\prac06-11.php 01:<HTML> 02: <BODY> 03: <?php 04: abstract class Payroll 05: 06: public $EmpName$ EmpName; 07: abstract public function Payment($Hours,, $PayRate$ PayRate,, $Bonus); 08: 09: class BonusPayroll extends Payroll 10: 11: public function Payment($Hours,, $PayRate$ PayRate,, $Bonus) 12: 13: return $Hours * $PayRate$ + $Bonus; 14: 15: 16:: echo ' 加上獎金之後的薪資為 '.BonusPayroll::Payment(100, 80, 500).'<BR>'; 17:?> 18: </BODY> 19:</HTML>
6-3-6 子類別的建構函式與解構函式 \ch06\prac06-12.php ( 下頁續 ) 01:<HTML> 02: <BODY> 03: <?php 04: class ParentClass // 定義父類別 05: 06: protected $Field1; // 定義父類別的屬性 07: function construct construct($value) // 定義父類別的建構函式 08: 09: $this->field1 = $Value; 10: echo ' 建立物件時成功地將 Field1 的值設定為 '.$this->field1.'<br>'; 11:
12: function destruct() // 定義父類別的解構函式 13: 14: $this->field1 = 0; 15: echo ' 摧毀物件時成功地將 Field1 的值設定為 '.$this->field1.'<br>'; 16: 17: 18: class ChildClass extends ParentClass // 定義子類別 19: 20: protected $Field2; // 定義子類別的屬性 21: 22: $MyObject$ = new ChildClass(100); // 會自動執行父類別的建構函式 23: $MyObject$ = NULL; // 會自動執行父類別的解構函式 24:?> 25: </BODY> 26:</HTML>
\ch06\prac06-13.php ( 下頁續 ) 01:<HTML> 02: <BODY> 03: <?php 04: class ParentClass // 定義父類別 05: 06: protected $Field1; // 定義父類別的屬性 07: function construct($value construct($value) // 定義父類別的建構函式 08: 09: $this->field1 = $Value; 10: echo ' 建立物件時成功地將 Field1 的值設定為 '.$this->field1.'<br>'; 11: 12: function destruct() // 定義父類別的解構函式 13: 14: $this->field1 = 0; 15: echo ' 摧毀物件時成功地將 Field1 的值設定為 '.$this->field1.'<br>'; 16: 17:
\ch06\prac06-13.php ( 接上頁 ) 18: class ChildClass extends ParentClass // 定義子類別 19: 20: protected $Field2; // 定義子類別的屬性 21: function construct construct($value) // 定義子類別的建構函式 22: 23: $this->field2 = $Value; 24: echo ' 建立物件時成功地將 Field2 的值設定為 '.$this->field2.'<br>'; 25: 26: function destruct() // 定義子類別的解構函式 27: 28: $this->field2 = 0; 29: echo ' 摧毀物件時成功地將 Field2 的值設定為 '.$this->field2.'<br>'; 30: 31: 32: $MyObject$ = new ChildClass(100); // 會自動執行子類別的建構函式 33: $MyObject$ = NULL; // 會自動執行子類別的建構函式 34:?> 35: </BODY> 36:</HTML>
6-3-7 類別階層 class Employee Name Salary 箭頭表示繼承自 箭頭表示繼承自 class Managers extends Employee class Asistants extends Employee Department ComputeBonus() Age ComputeBonus()
6-3-8 使用繼承的時機 子類別應該屬於父類別的一種, 而不只是和父類別有關聯 繼承可以提高程式的重複使用性 繼承適用於類別階層少的情況 繼承可以用來實作多型
6-4 介面 interface interface_name [ 定義成員但不提供實作方式 ] class class_name implements interface_name [ 提供成員的實作方式 ]
\ch06\prac06-15.php 01:<HTML> 02: <BODY> 03: <?php 04: interface MyInterface // 定義名稱為 MyInterface 的介面 05: 06: function Method1(); // 定義方法但不提供實作方式 07: function Method2(); // 定義方法但不提供實作方式 08: 09: 10: class MyClass implements MyInterface // 此類別用來實作 MyInterface 介面的成員 11: 12: function Method1() // 提供 Method1() 方法的實作方式 13: 14: echo ' 這是 MyInterface 介面定義的 Method1() 方法 <BR>'; 15: 16: function Method2() // 提供 Method2() 方法的實作方式 17: 18: echo ' 這是 MyInterface 介面定義的 Method2() 方法 <BR>'; 19: 20: 21: 22: MyClass::Method1(); 23: MyClass::Method2(); 24:?> 25: </BODY> 26:</HTML>
6-5-1 使用繼承實作多型 6-5 多型 \ch06\prac06-16.php ( 下頁續 ) <HTML> <BODY> <?php abstract class Transport public abstract function Launch(); public abstract function Stop(); class Bicycle extends Transport // 定義繼承自交通工具父類別的腳踏車子類別 public function Launch() // 覆蓋繼承自交通工具父類別的啟動方法 // 寫上啟動腳踏車的程式碼
\ch06\prac06-16.php ( 接上頁 ) public function Stop() // 覆蓋繼承自交通工具父類別的停止方法 // 寫上停止腳踏車的程式碼 class Motorcycle extends Transport // 定義繼承自交通工具父類別的摩托車子類別 public function Launch() // 覆蓋繼承自交通工具父類別的啟動方法 // 寫上啟動摩托車的程式碼 public function Stop() // 覆蓋繼承自交通工具父類別的停止方法 // 寫上停止摩托車的程式碼 class Car extends Transport // 定義繼承自交通工具父類別的汽車類別 public function Launch() // 覆蓋繼承自交通工具父類別的啟動方法 // 寫上啟動汽車的程式碼 public function Stop() // 覆蓋繼承自交通工具父類別的停止方法 // 寫上停止汽車的程式碼?> </BODY> </HTML>
6-5-2 使用介面實作多型 \ch06\prac06-17.php ( 下頁續 ) 01:<HTML> 02: <BODY> 03: <?php 04: interface Shape 05: 06: public function CalculateArea($X,, $Y); 07: 08: 09: class Triangle extends Shape // 此三角形類別用來實作 Shape 介面 10: 11: public function CalculateArea($X,, $Y) // 提供 CalculateArea() 方法的實作方式 12: 13: return ($X * $Y) / 2; // 計算三角形面積 ( 底乘以高除以 2) 14: 15: 16:
17: class Rectangle extends Shape // 此矩形類別用來實作 Shape 介面 18: 19: public function CalculateArea($X,, $Y) // 提供 CalculateArea() 方法的實作方式 20: 21: return ($X * $Y); // 計算矩形的面積 ( 長乘以寬 ) 22: 23: 24: $Obj1 = new Triangle() // 建立三角形類別的物件 25: $Obj2 = new Rectangle(); // 建立矩形類別的物件 26: echo ' 底為 10 高為 20 的三角形面積為 '.$Obj1->CalculateArea(10, 20).'<BR>'; 27: echo ' 長為 10 寬為 20 的矩形面積為 '.$Obj2->CalculateArea(10, 20).'<BR>'; 28:?> 29: </BODY> 30:</HTML>
6-6 類別相關函式 is_a(obj obj, class_name) is_subclass_of(obj obj, class_name) class_exists(class_name class_name) method_exists(obj obj, method_name) get_class(obj obj) get_class_methods(class_name class_name) get_class_vars(class_name class_name) get_declared_classes() get_declared_interfaces() get_object_vars(obj obj) get_parent_class(arg arg) call_user_method(method_name method_name, obj [, arg1 [, arg2a [, ]]]) call_user_method_array(method_name method_name, obj [, array arg])