PHP封裝、繼承和多型

2020-07-16 10:05:30
眾所周知,物件導向的程式語言有三大特性,分別是:封裝、繼承和多型。

物件導向的封裝特性就是將類中的成員屬性和方法內容細節盡可能地隱藏起來,確保類外部程式碼不能隨意存取類中的內容。

物件導向的繼承特性使得子類可繼承父類別中的屬性和方法,提高類程式碼的複用性。

物件導向的多型特性是最常用到的一種特性。所謂多型,是指同一個東西不同形態的展示。

PHP 也是物件導向的程式語言,它也支援這三大特性。

PHP 封裝

可使用 public、protected、private 來修飾物件的屬性和方法。使用不同修飾符的屬性和方法其可被存取的許可權也不同:
  • 使用 public 修飾的屬性和方法可以在任何地方呼叫,如果在類中的屬性和方法前面沒有修飾符,則預設修飾符為 public。
  • 使用 protected 修飾的屬性和方法可在本類和子類中被呼叫,在其他地方呼叫將會報錯。
  • 使用 private 修飾的屬性和方法只能在本類中被存取。

關於修飾符的使用範例如下:
<?php
class yourclass{
    public $name;
    private $age;
    protected $weight;
    function __construct($name,$age,$weight){
        $this->name = $name;
        $this->age = $age;
        $this->weight = $weight;
    }
    private function get($key){
        return $this->$key;
    }
}
class hisclass extends yourclass{
    function key($key){
        //父類別中get方法為private, 子類中不可存取, 故重新定義一個相同功能的函數
        return $this->$key;
    }
}
$obj = new yourclass('tom',22,'60kg');
echo $obj->name;
//echo $obj->age;  // 將會報錯
echo $obj->get('age');  // 可通過呼叫公共方法存取
$son = new hisclass('jim',23,'70kg');
echo $son->name;
echo $son->key('weight');
echo $son->key('age');  // 存取不到$age
?>
執行以上程式的輸出結果為:

tom  22  jim  70kg

PHP 繼承

把一個類作為公共基礎類別,其他的類繼承自這個基礎類別,則其他類中都具有這個基礎類別的屬性和方法,其他類也可各自額外定義自己不同的屬性和方法。

類的繼承使用關鍵詞extends,在子類中可使用parent存取父類別的方法。在子類中可重寫父類別的方法。

關於類繼承特性的程式碼如下:
<?php
class yourclass{
    public $name;
    private $age;
    protected $weight;
    function __construct($name,$age,$weight){
        $this->name = $name;
        $this->age = $age;
        $this->weight = $weight;
    }
    function like(){
        echo "I like money. ";
    }
    function age(){
        echo $this->name . ' is ' . $this->age . 'years old';
    }
    protected function get($key){
        return $this->$key;
    }
    function set($key,$value){
        $this->$key = $value;
    }
}
class hisclass extends yourclass{
    function get($key){  //重寫父類別方法
        echo $this->key;
    }
    function what(){
        parent::like();  //子類中存取父類別方法
    }
    function getAge(){
        $this->age();  //呼叫從父類別繼承來的方法
    }
}
$obj = new hisclass('tom',22,'60kg');  //使用繼承自父類別的__construct方法初始化範例
$obj->get('name');
$obj->what();
$obj->set('age',33);
$obj->getAge();
?>
執行以上程式的輸出結果為:     

I like money. tom is 33years old

PHP 多型

多型通過繼承複用程式碼而實現,可編寫出健壯可延伸的程式碼,減少流程控制語句(if else)的使用,例如:
<?php
class animal{
    function can(){
        echo "this function weill be re-write in the children";
    }
}
class cat extends animal{
    function can(){
        echo "I can climb";
    }
}
class dog extends animal{
    function can(){
        echo "I can swim";
    }
}
function test($obj){
    $obj->can();
}
test(new cat());
test(new dog());
?>
上述例子便體現了物件導向的多型性,可以改進程式碼將 animal 類定義為抽象類,或者使用介面都是可以的,這樣就無須在父類別的方法中定義無意義的函數體了。