2021年3月13日 星期六

PHP 多型方法與多載功能

設定目標:
  • 了解 PHP 如何使用多型方法
  • 了解 PHP 如何使用多載功能

多型概念與使用方法
  1. 多型(Polymorphism)
    • 使用概念與方法:
      • 有繼承的關係才能使用多型
      • 利用有相同父類別的關係,進行不同子類別的方法實作,產生不同的結果!
    • 例:demo5.php
      <?php
      abstract class Animal {
        public function sleep(){
            echo '睡';
        }
      }
      class Dog extends Animal {
        public function move(){
            echo '跑';
        }
      }
      class Bird extends Animal{
        public function move()
        {
            echo '飛';
        }
      }
      class Action{
        public function actionMove(Animal $obj)
        {
            $obj->move();
        }
      }
      
      $dog = new Dog();
      $bird = new Bird();
      $action = new Action();
      $action->actionMove($dog);
      $action->actionMove($bird);
      ?>
      
多載功能的應用
  1. 多載(overloading)
    • PHP 無法像其他物件導向程式語言,可以利用相同名稱,不同參數屬性值來實作多載功能!
    • PHP 利用自定義的 Magic methods 來實作多載功能!
    • 屬性多載的 magic function :
      • __set(): 若有屬性名稱是設定未定義或無法讀取的,就「設定」對應的屬性值!
      • __get(): 若有屬性名稱是設定未定義或無法讀取的,就「取得」對應的屬性值!
      • __isset(): 查詢某個屬性是否有被定義!
      • __unset(): 解除某個屬性定義值!
      • 範例 : Person.php
        <?php
          class Person {
              private $sex;
              public function __set($name, $value){
                
                //限制不可動態產生屬性
                if (isset($this->$name)) {
                    return $this->$name = $value;
                } else {
                    return null;
                }
              }
              // 取得屬性名稱的值
              public function __get($name){
                return $name;
              }
              // 判斷是否有該屬性參數   
              public function __isset($name){
                return $name;
              }
              // 取消該屬性
              public function __unset($name){
                return $name;
              }
            }
            
            $person = new Person();
            //Person 類別沒有 name 這個屬性名稱
            //PHP_EOL 空隔或是換行
            $person->name = 'PHP';
            echo $person->name.PHP_EOL;
            // sex 這個屬性是無法取得的
            echo $person->sex.PHP_EOL;
            echo isset($person->address);
            unset($person->name);
        ?>
        
    • 方法多載的 magic functions :
      • __call() : 當呼叫一個未定義的物件方法時,會呼叫本法函數!
      • __callStatic() : 當呼叫一個未定義的靜態物件的方法時,會呼叫本法函數!
      • 例 : Shape.php
        <?php
        class Shape {
          const PI = 3.142 ;
          // name 是方法名稱,arg 則是陣列名稱
          function __call($name,$arg){
            if($name == 'area')
              switch(count($arg)){
                case 0 : return 0 ;
                //self 指物件自己
                case 1 : return self::PI * $arg[0] ;
                case 2 : return $arg[0] * $arg[1];
              }
          }
          function __callStatic($name,$arg){
            return array(3,5);
          }
        }
        $circle = new Shape();
        echo $circle->area(3);
        $rect = new Shape();
        echo $rect->area(8,6);
        echo Sharp::hello()[1];
        ?>
        

本章練習:
  • 寫個利用衣服的類別,讓你的 dog 、cat 以及 human 穿上適合的衣服!
  • 寫個檢查有沒有穿衣服的方法,讓 dog 、cat 不用穿衣服,以及 human 穿上泳衣!