Traits的用法

來源:互聯網
上載者:User
原文出處:http://blog.csdn.net/longlongmylove/article/details/7521379

php5.4新功能Traits介紹

1. traits
Traits是在5.4中新增的一個用於實現代碼重用的方法。

php是一種單一繼承的語言,我們無法像java一樣在一個class中extends多個基類來實現代碼重用,現在Traits能解決這一代碼重用的問題,它能讓開發人員在多個不同的class中實現代碼重用。
Traits和class在語義的定義上都是為了減少代碼的複雜性,避免多重繼承的問題。

Traits 和class相似,但是僅用於以統一和較細粒度的方式來提供一組功能,在Traits內部無法進行執行個體化,即不存在類似class的建構函式__construct()。Traits作為一個php傳統繼承的擴充並實現水平整合;因此,在應用程式的class中可以不再需要繼承。

1)如何使用
在類中用關鍵字'use' 來引用 Traits。多個Traits 用','隔開。

執行個體代碼如下:

[php] view plaincopy

  1. trait ezcReflectionReturnInfo {
  2. function getReturnType() {
  3. }
  4. function getReturnDescription() {
  5. }
  6. }class ezcReflectionMethod extends ReflectionMethod {
  7. use ezcReflectionReturnInfo;
  8. /* ... */
  9. }
  10. class ezcReflectionFunction extends ReflectionFunction {
  11. use ezcReflectionReturnInfo;
  12. /* ... */
  13. }
  14. ?>

2)優先順序
基類中的成員函數將被Traits中的函數覆蓋,當前類中的成員函數將覆蓋Traits中的函數。

[php] view plaincopy

  1. class Base {
  2. public function sayHello() {
  3. echo 'Hello ';
  4. }
  5. }
  6. trait SayWorld {
  7. public function sayHello() {
  8. parent::sayHello();
  9. echo "World!\n";
  10. }
  11. }
  12. class MyHelloWorld extends Base {
  13. use SayWorld;
  14. }
  15. class MyHelloWorldExt extends Base {
  16. use SayWorld;
  17. public function sayHello() {
  18. /**
  19. * 這裡是5.4中的新的改動,5.4之前的版本會提示:
  20. * PHP Fatal error: Cannot use string offset as an array
  21. * 5.4中改進為返回字串中的該索引號的字元
  22. */
  23. $str = "Arvin";
  24. echo $str[0][0];// echo 'A';
  25. }
  26. public function shortArray() {
  27. $array = ['first', 2, 3, 4];//5.4中的數組簡單文法
  28. echo $array[0];//5.4中的數組解引用取數組元素方法
  29. }
  30. }
  31. $o = new MyHelloWorld();
  32. $o->sayHello();
  33. $oe = new MyHelloWorldExt();
  34. $oe->sayHello();
  35. echo "\n";
  36. $oe->shortArray();

[php] view plaincopy

  1. 輸出:
  2. Hello World!
  3. A
  4. first

3)多Traits

多個Traits可以添加到一個class的聲明中,多個Traits之間用","隔開。

[php] view plaincopy

  1. trait Hello {
  2. public function sayHello() {
  3. echo 'Hello ';
  4. }
  5. }
  6. trait World {
  7. public function sayWorld() {
  8. echo 'World';
  9. }
  10. }
  11. class MyHelloWorld {
  12. use Hello, World;
  13. }
  14. $o = new MyHelloWorld();
  15. $o->sayHello();
  16. $o->sayWorld();
  17. ?>

輸出結果:

Hello World4)多Traits衝突
如果添加到同一個class的兩個Traits中有相同的函數名稱,且沒有明確的進行處理,將產生一個錯誤。
為瞭解決同一個類中兩個Tratis中的同名函數衝突,需要用insteadof操作符來選擇正確的函數。
因為方法的唯一性和排他性,'as'操作符允許用在衝突函數之後以解決內部衝突的問題。

[php] view plaincopy

  1. trait A {
  2. public function smallTalk() {
  3. echo 'a';
  4. }
  5. public function bigTalk() {
  6. echo 'A';
  7. }
  8. }
  9. trait B {
  10. public function smallTalk() {
  11. echo 'b';
  12. }
  13. public function bigTalk() {
  14. echo 'B';
  15. }
  16. }
  17. class Talker {
  18. use A, B {
  19. B::smallTalk insteadof A;
  20. A::bigTalk insteadof B;
  21. }
  22. }
  23. class Aliased_Talker {
  24. use A, B {
  25. B::smallTalk insteadof A;
  26. A::bigTalk insteadof B;
  27. B::bigTalk as talk;
  28. }
  29. }
  30. ?>

上面的例子中,Talker使用Traits A 和B,因此兩者中相同的函數名稱存在衝突。
alker中定義了smallTalk取自Traits B,bigTalk取自Traits A。
Aliased_Talker中通過使用as操作符來確保Traits B中的bigTalk通過別名talk來實現。
5)改變函數存取權限
我們可以使用as文法來改變Traits中函數的存取權限屬性。

[php] view plaincopy

  1. trait HelloWorld {
  2. public function sayHello() {
  3. echo 'Hello World!';
  4. }
  5. }
  6. // Change visibility of sayHello,改變sayHello的存取權限。
  7. class MyClass1 {
  8. use HelloWorld { sayHello as protected; }
  9. }
  10. // Alias method with changed visibility
  11. // sayHello visibility not changed,設定別名myPrivateHello。
  12. class MyClass2 {
  13. use HelloWorld { sayHello as private myPrivateHello; }
  14. }
  15. ?>

6)Traits組成新Traits
就像許多類一樣可以在類中使用Traits,Traits中一樣可以使用Traits。可以在一個Traits中定義一個或者多個Traits,這些Traits 可以作為部分或者全部成員被定義在其他Traits中。

[php] view plaincopy

  1. trait Hello {
  2. public function sayHello() {
  3. echo 'Hello ';
  4. }
  5. }
  6. trait World {
  7. public function sayWorld() {
  8. echo 'World!';
  9. }
  10. }
  11. trait HelloWorld {
  12. use Hello, World;
  13. }
  14. class MyHelloWorld {
  15. use HelloWorld;
  16. }
  17. $o = new MyHelloWorld();
  18. $o->sayHello();
  19. $o->sayWorld();
  20. ?>

以上常式會輸出:

[php] view plaincopy

  1. Hello World!

7)抽象Trait成員
為了在類中強制實現某些方法,可以在Traits中使用抽象方法。
例如:

[php] view plaincopy

  1. trait Hello {
  2. public function sayHelloWorld() {
  3. echo 'Hello '.$this->getWorld();
  4. }
  5. abstract public function getWorld();
  6. }
  7. class MyHelloWorld {
  8. private $world;
  9. use Hello;
  10. public function __construct($world) {
  11. $this->world = $world;
  12. }
  13. public function getWorld() {
  14. return $this->world;
  15. }
  16. }
  17. /**
  18. * 這裡用到了5.4新功能 類執行個體化解引用操作
  19. * (new class())->method();
  20. */
  21. (new MyHelloWorld('Arvin'))->sayHelloWorld();
  22. ?>
  23. 該執行個體輸出:
  24. Hello Arvin

8)靜態Trait成員

在Traits中不能定義static 靜態變數,但是可以定義在Tratis的函數中。Tratis中同樣可以定義靜態函數。

[php] view plaincopy

  1. trait Counter {
  2. public function inc() {
  3. static $c = 0;//靜態變數
  4. $c += 1;
  5. echo "$c\n";
  6. }
  7. /**
  8. * 靜態方法
  9. */
  10. public static function doSomething() {
  11. echo 'Doing something';
  12. }
  13. }
  14. class C1 {
  15. use Counter;
  16. }
  17. (new C1())->inc(); // echo 1
  18. C1::doSomething();
  19. ?>
  20. 輸出為:
  21. 1
  22. Doing something

9) Traits 定義屬性

如果在一個trait中定義了一個屬性,則在引用該trait的類中不能定義同名的屬性,如果該類中定義有和trait中已定義屬性具有相同的名字和訪問可見度,則是一個E_STRICT 提示,否則拋出語法錯誤。

x, $example->y;?>輸出:12

在最後貼上php5.4.0部分新功能changelog:

Added short array syntax support ([1,2,3]), see UPGRADING guide for full details.Added binary numbers format (0b001010).Added support for Class::{expr}() syntax.Added support for Traits.//本文的主要內容Added closure $this support back.Added array dereferencing support.//數組解引用支援,上文中有執行個體Added callable typehint.Added indirect method call through array. #47160.Added DTrace support.//傳說DTrace是一個效能分析工具,可以跟蹤出函數調用點,返回點等資料Added class member access on instantiation (e.g. (new foo)->bar()) support.//類新執行個體解引用操作,上文中有執行個體
本文旨在拋磚引玉,希望大家一起繼續探究php5.4的新功能。^_^

以上就介紹了Traits的用法,包括了方面的內容,希望對PHP教程有興趣的朋友有所協助。

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.