PHP – 特性



在 PHP 中,一個類只能繼承自一個父類,PHP 中未定義多重繼承。PHP 中的特性是為了克服此限制而引入的。您可以在特性中定義一個或多個方法,這些方法可以在各種獨立類中自由重用。

語法

“trait”關鍵字按以下語法使用:

trait mytrait {
   function method1() {
      /*function body*/
   }

   function method2() {
      /*function body*/
   }
}

為了能夠呼叫特性中的方法,需要使用 use 關鍵字將其提供給另一個類。

示例

特性類似於類,但僅用於以細粒度和一致的方式對功能進行分組。無法單獨例項化特性。

<?php
   trait mytrait {
      public function hello() {
         echo "Hello World from " . __TRAIT__ . "";
      }
   }
   class myclass {
      use mytrait;
   }
   $obj = new myclass();
   $obj->hello();
?>

它將產生以下輸出

Hello World from mytrait

示例

特性可以在多個類中使用。以下示例具有一個包含 avg() 函式的 mytrait。它用於 marks 類中。percent() 方法在內部呼叫特性中的 avg() 函式。

請檢視以下示例:

<?php
   trait mytrait {
      function avg($x, $y) {
         return ($x+$y)/2;
      }
   }
   class marks {
      use mytrait;
      private int $m1, $m2;
      function __construct($x, $y) {
         $this->m1 = $x;
         $this->m2 = $y;
      }
      function percent():float {
         return $this->avg($this->m1, $this->m2);
      }
   }
   $obj = new marks(50, 60);
   echo "percentage: " . $obj->percent();
?>

它將產生以下輸出

percentage: 55

使用多個特性

一個類可以使用多個特性。這裡我們有兩個特性,每個特性都有一個函式,分別執行兩個數字的加法和乘法。兩者都用於第三個類中。

<?php
   trait addition {
      function add($x, $y) {
         return $x+$y;
      }
   }

   trait multiplication {
      function multiply($x, $y) {
         return $x*$y;
      }
   }

   class numbers {
      use addition, multiplication;
      private int $m1, $m2;
      function __construct($x, $y) {
         $this->m1 = $x;
         $this->m2 = $y;
      }
      function calculate():array {
         $arr = [$this->add($this->m1, $this->m2), $this->multiply($this->m1, $this->m2)];
         return $arr;
      }
   }

   $obj = new numbers(50, 60);
   $res = $obj->calculate();
   echo "Addition: " . $res[0] . PHP_EOL;
   echo "Multiplication: " . $res[1] . PHP_EOL;
?>

它將產生以下輸出

Addition: 110
Multiplication: 3000

覆蓋特性函式

當一個類使用某個特性時,它的函式就像子類繼承父方法一樣對它可用。也可以覆蓋特性函式。

<?php
   trait mytrait {
      public function sayHello() {
         echo 'Hello World!';
      }
   }

   class myclass {
      use mytrait;
      public function sayHello() {
         echo 'Hello PHP!';
      }
   }

   $o = new myclass();
   $o->sayHello();
?>

它將產生以下輸出

Hello PHP!

“insteadof”關鍵字

有時,兩個或更多特性可能具有相同名稱的函式。因此,在類中使用它們會產生模稜兩可的情況。PHP 提供 insteadof 關鍵字來告訴解析器您打算使用哪個特性的函式。

<?php
   trait mytrait {
      public function sayHello() {
         echo 'Hello World!';
      }
   }

   trait newtrait {
      public function sayHello() {
         echo 'Hello PHP!';
      }
   }

   class myclass {
      use mytrait, newtrait{
         newtrait::sayHello insteadof mytrait;
      }
   }

   $o = new myclass();
   $o->sayHello();
?>

它將產生以下輸出

Hello PHP!

特性函式的別名

如果希望能夠呼叫來自兩個特性的函式,即使它們具有相同名稱的函式,也可以透過為其中一個指定別名作為解決方法。

示例

在以下示例中,我們將 mytrait 中的 sayHello() 稱為 hello():

<?php
   trait mytrait {
      public function sayHello() {
         echo 'Hello World!' . PHP_EOL;
      }
   }

   trait newtrait {
      public function sayHello() {
         echo 'Hello PHP!' . PHP_EOL;
      }
   }

   class myclass {
      use mytrait, newtrait{
         mytrait::sayHello as hello;
         newtrait::sayHello insteadof mytrait;
      }
   }

   $o = new myclass();
   $o->hello();
   $o->sayHello();
?>

它將產生以下輸出

Hello World!
Hello PHP!
廣告