在PHP中,多型性是指同一個操作作用於不同的類的範例,將產生不同的執行結果。也即不同類的物件收到相同的訊息時,將得到不同的結果;不同的物件,收到同一訊息將可以產生不同的結果,這種現象稱為多型性。多型性允許每個物件以適合自身的方式去響應共同的訊息;多型性增強了軟體的靈活性和重用性。
本教學操作環境:windows7系統、PHP8版、DELL G3電腦
多型性是指相同的操作或函數、過程可作用於多種型別的物件上並獲得不同的結果。不同的物件,收到同一訊息將可以產生不同的結果,這種現象稱為多型性。
多型性允許每個物件以適合自身的方式去響應共同的訊息。多型性增強了軟體的靈活性和重用性。
在物件導向的軟體開發中,多型性是最為重要的部分之一。物件導向程式設計並不只是將相關的方法與資料簡單的結合起來,而是採用物件導向程式設計中的各種要素將現實生活中的各種情況清晰的描述出來。這一小節將對物件導向程式設計中的多型性作詳細的講解。
1.什麼是多型
多 態(Polymorphism)按字面上意思理解就是「多種形狀」。可以理解為多種表現形式,也即「一個對外介面,多個內部實現方法」。在物件導向的理論 中,多型性的一般定義為:同一個操作作用於不同的類的範例,將產生不同的執行結果。也即不同類的物件收到相同的訊息時,將得到不同的結果。
在實際的應用開發中,採用物件導向中的多型主要在於可以將不同的子類物件都當作一個父類別來處理,並且可以遮蔽不同子類物件之間所存在的差異,寫出通用的程式碼,做出通用的程式設計,以適應需求的不斷變化。
2. 多型的應用設計
在實際的應用開發中,通常為了使專案能夠在以後的時間裡的輕鬆實現擴充套件與升級,需要通過繼承實現可複用模組進行輕鬆升級。在進行可複用模組設計時,就需要儘可能的減少使用流程控制語句。此時就可以採用多型實現該類設計。
【範例】例舉了通常採用流程控制語句實現不同類的處理。其程式碼如下所示。
class painter{ //定義油漆工類
public function paintbrush(){ //定義油漆工動作
echo "油漆工正在刷漆!\n";
}
}
class typist{ //定義打字員類
public function typed(){ //定義打字員工作
echo "打字員正在打字!\n";
}
}
function printworking($obj){ //定義處理類
if(objinstanceofpainter)//若物件是油漆工類,則顯示油漆工動作$obj−>paintbrush();elseif(obj instanceof typist){ //若物件是打字員類,則顯示打字員動作
$obj->typed();
}else{ //若非以上類,則顯示出錯資訊
echo "Error: 物件錯誤!";
}
}
printworking(new painter()); //顯示員工工作
printworking(new typist()); //顯示員工工作
登入後複製
分析:在上述程式中,首先定義兩個員工類:油漆工類和打字員類。然後定義一個處理常式,在該函數中,判斷員工是否為已經定義的員工,列印出員工的工作狀態。其結果如下所示。
油漆工正在刷漆
打字員正在打字
登入後複製
從 以上程式可輕鬆看出,若想顯示其幾種員工的工作狀態,需要首先定義該員工類,並在該員工類中定義員工的工作,然後在printworking()函數中增 加elseif語句以檢查物件是哪一員工類的範例。這在實際的應用中,是非常不可取的。若此時採用多型,則可以輕鬆解決此問題。
可以首先建立一個員工父類別,所有的員工類將繼承自該員工父類別,並且繼承父類別的所有方法與屬性。然後在員工類中建立「是一」關係,判斷是否為合法的員工。
【範例】例舉了採用多型的方式改寫上例。其程式碼如下所示。
class employee{//定義員工父類別
protected function working(){//定義員工工作,需要在子類的實現
echo "本方法需要在子類中過載!";
}
}
class painter extends employee{//定義油漆工類
public function working(){//實現繼承的工作方法
echo "油漆工正在刷漆!\n";
}
}
class typist extends employee{//定義打字員類
public function working(){
echo "打字員正在打字!\n";
}
}
class manager extends employee{//定義經理類
public function working(){
echo "經理正在開會!";
}
}
function printworking($obj){//定義處理方法
if($obj instanceof employee){//若是員工物件,則顯示其工作狀態
$obj->working();
}else{//否則顯示錯誤資訊
echo "Error: 物件錯誤!";
}
}
printworking(new painter());//顯示油漆工的工作
printworking(new typist());//顯示打字員的工作
printworking(new manager());//顯示經理的工作
登入後複製
分析:在上述程式中,首先定義一個員工基礎類別,並定義一個員工工作狀態的方法。然後定義將繼承自員工基礎類別的三個員工類:油漆工類、打字員類和經理類。然後定義顯示員工工作狀態的方法。並在該方法中建立一個「是一」關係,用於判斷是否為合法的員工。其結果如下所示。
油漆工正在刷漆!
打字員正在打字!
經理正在開會!
登入後複製
從上例可發現,無論增加多少個員工類,只需要實現自員工父類別繼承的該員工類和方法。而無須修改顯示員工工作狀態的方法printworking()。
實現php多型的兩種方法
在PHP5中,變數的型別是不確定的,一個變數可以指向任何型別的數值、字串、物件、資源等。我們無法說PHP5中多型的是變數。
我們只能說在PHP5中,多型應用在方法引數的型別提示位置。
一個類的任何子類物件都可以滿足以當前型別作為型別提示的型別要求。
所有實現這個介面的類,都可以滿足以介面型別作為型別提示的方法引數要求。
簡單的說,一個類擁有其父類別、和已實現介面的身份。
通過實現介面實現多型
<?php
interface User{ // User介面
public function getName();
public function setName($_name);
}
class NormalUser implements User { // 實現介面的類.
private $name;
public function getName(){
return $this->name;
}
public function setName($_name){
$this->name = $_name;
}
}
class UserAdmin{ //操作.
public
static
function ChangeUserName(User $_user,$_userName){
$_user->setName($_userName);
}
}
$normalUser = new NormalUser();
UserAdmin::ChangeUserName($normalUser,"Tom");//這裡傳入的是 NormalUser的範例.
echo $normalUser->getName();
?>
登入後複製
使用介面與組合模擬多繼承
通過組合模擬多重繼承。
在PHP中不支援多重繼承,如果我們向使用多個類的方法而實現程式碼重用有什麼辦法麼?
那就是組合。在一個類中去將另外一個類設定成屬性。
下面的例子,模擬了多重繼承。
介面範例
寫一個概念性的例子。 我們設計一個線上銷售系統,使用者部分設計如下: 將使用者分為,NormalUser, VipUser, InnerUser 三種。要求根據使用者的不同折扣計算使用者購買產品的價格。並要求為以後擴充套件和維護預留空間。
<?php
interface User
{
public function getName();
public function setName($_name);
public function getDiscount();
}
abstract class AbstractUser implements User
{
private $name = "";
protected $discount = 0;
protected $grade = "";
function construct($_name) {
$this->setName($_name);
}
function getName() {
return $this->name;
}
function setName($_name) {
$this->name = $_name;
}
function getDiscount() {
return $this->discount;
}
function getGrade() {
return $this->grade;
}
}
class NormalUser
extends
AbstractUser
{
protected $discount = 1.0;
protected $grade = "Normal";
}
class VipUser extends AbstractUser
{
protected $discount = 0.8;
protected $grade = "VipUser";
}
class InnerUser extends AbstractUser
{
protected $discount = 0.7;
protected $grade = "InnerUser";
}
interface Product
{
function getProductName();
function getProductPrice();
}
interface Book extends Product
{
function getAuthor();
}
class BookOnline implements Book
{
private $productName;
protected $productPrice;
protected $Author;
function construct($_bookName) {
$this->productName = $_bookName;
}
function getProductName() {
return $this->productName;
}
function getProductPrice() {
$this->productPrice = 100;
return $this->productPrice;
}
public function getAuthor() {
$this->Author = "chenfei";
return $this->Author;
}
}
class Productsettle
{
public static function finalPrice(User $_user, Product $_product, $number) {
$price = $_user->getDiscount() * $_product->getProductPrice() * $number;
return $price;
}
}
$number = 10;
$book = new BookOnline("
設計模式
");
$user = new NormalUser("tom");
$price = Productsettle::finalPrice($user, $book, $number);
$str = "您好,尊敬的" . $user->getName() . "<br />";
$str .= "您的級別是" . $user->getGrade() . "<br />";
$str .= "您的折扣是" . $user->getDiscount() . "<br />";
$str .= "您的價格是" . $price;
echo $str;
?>
登入後複製
推薦學習:《》
以上就是PHP中多型性是什麼意思的詳細內容,更多請關注TW511.COM其它相關文章!