iT邦幫忙

2025 iThome 鐵人賽

DAY 24
0
Modern Web

PHP 新手自學筆記系列 第 24

【Day24】 PHP 多型 (抽象類別)

  • 分享至 

  • xImage
  •  

多型的定義是 : 不同類別的物件可以 使用相同的方法名稱,但實際行為可以不同

多型是一種概念,像介面(interface)、抽象類別(Abstract Classes)都是實現多型的工具。一般類別只要使用相同方法名稱、行為不同,也算多型,但在大型專案中,通常會用抽象類別或介面來實作多型,以保證規範和可維護性。

由於 一個要理解一段時間 所以 今天先學抽象類別 明天在學 介面 ~

抽象類別 聽起來很抽象 但它的名字就叫抽象類別 它的方法(function)就叫抽象方法

為什麼要用抽象類別,不用一般類別就好? 簡單來說:抽象類別具有強制規範,如果做不到這些規範就Error,適合大型專案,可以防止子類別遺漏沒寫到,一般類別就算沒寫也不會error

抽象類別的使用規範

項目 規則
抽象類別 不能直接實例化 (new)
抽象方法 子類別 必須覆寫,否則報錯
已實作方法 子類別可以選擇覆寫,也可以直接使用
繼承 抽象類別可以繼承抽象類別,多層抽象藍圖可分層設計

它的規範看起來可能很模糊 看一下程式碼 (先看錯誤範例)

<?php
abstract class phone //抽象類別
{
    abstract function call(); //抽象方法 (這邊要加 ; 哦)
    {
        echo "hello~";
    }  
    public function sendMessage()
    {
        echo "發送簡訊<br>";
    }
}

$apple = new phone(); 
$apple->sendMessage(); 

這段程式碼會報錯 有2個原因

abstract function call() ; //抽象方法(裡面不放實作) -> 子類別必須實作
    {
        echo "hello~~" ;
    }

$apple = new phone();//這裡不能直接實例化
$apple->sendMessage();  // 上面物件沒建立 這裡也不可能成功

看到這裡可以大概理解,抽象方法裡面不能放任何程式碼,物件也不能直接實例化,再來看一段程式碼,一次解釋抽象方法的作用以及怎麼實例化

<?php
abstract class phone
{
    abstract function call();
    public function sendMessage()
    {
        echo "發送簡訊<br>";

    }
}
class SmartPhone extends phone{
    public function call(){
        echo "智慧撥號<br>";
    }
}

class OldPhone extends phone{
    public function call(){
        echo "傳統撥號<br>";
    }
}
$iphone = new SmartPhone();
$iphone->call(); //智慧撥號
$oldphone = new OldPhone();
$oldphone->call(); // 傳統撥號
$oldphone->sendMessage(); //發送簡訊
?>

這邊可以看到 建立物件 是建立子類別的物件,子類別又是繼承抽象方法的,所以抽象類別不能直接建立物件,要由子類別繼承然後才建立子類別物件。
可以看到子類別 SmartPhone 和 OldPhone 都有 call() 方法,這就是對抽象方法的實作。不同子類別的 call() 方法雖然名稱相同,但行為不同,這就是多型的概念。
這邊補充一下 實作的定義就是有用到這個方法就算實作, {} 裡面可以不用有程式碼,程式碼會長這樣。

abstract class Phone {
    abstract function call();
}

class iPhone extends Phone {
    public function call() { }  // 已實作,空內容也合法
}

總結來說 抽象類別 就是 比 一般類別 多了 規範 能保證子類別實作必要方法,也方便大型專案中使用多型


上一篇
【Day23】 PHP 封裝
系列文
PHP 新手自學筆記24
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言