首頁  >  文章  >  後端開發  >  總是在重複,氣抖冷,trait何時才能站起來?

總是在重複,氣抖冷,trait何時才能站起來?

autoload
autoload原創
2021-03-04 17:39:072227瀏覽

類別中的某些成員如何被其他類別使用呢?使用繼承的話,這繼承鏈也太長了,為了方便,php提供了程式碼重複使用技術trait。

  1.定義Trait 是為類似 PHP 的單一繼承語言而準備的一種程式碼重複使用機制。 trait可以使得單一繼承語言擺脫為了復用,而不得不繼承的尷尬處境,讓物件導向變得更純粹。

  2.基礎語法

     trait是類似class的關鍵字。

<?php
     trait Eat{
        public $a=10;      //trait内允许有类的成员属性(包括静态属性),成员方法(包括静态方法)
        public static $b=666;
        //const c=3.14;       //trait内不允许有常量
        protected $e;	//允许定义,但是实际不用
        private $f;
        public function getA()
        {
               echo $this->a,"<br>";
        }
        public static function getB()
        {
               echo self::$b,"<br>";
        }
    }
?>

     trait是用來實現程式碼的複用的,不能被實例化也不可以被繼承(因為根本不是類別)。

<?php
   trait Eat{}
  // $a=new Eat;//报错
  //calss A extends Eat{}//报错
?>

  3.trait的使用

     trait只是一段程式碼的集合,使用時必須使用use#來引用。

<?php
    
    trait Eat{
        public $a=10;
        public static $b=666;
        //const c=3.14;
        public function getA()
        {
               echo $this->a,"<br>";
        }
        public static function getB()
        {
               echo self::$b,"<br>";
        }
    }
    
    class A{
        use Eat;


        public function getC()
        {
            echo $this->a,"<br>";
        }
    }

    $boy=new A();
    $boy->getC();
    $boy->getA();
    $boy->getB();
?>

      一個類別可以使用多個trait。

<?php
   trait A1{
   }
   trait A2{
   }
   class People{
     use A1,A2;
   }
?>

  4.trait使用的問題

#      a.如果同時引入的多個trait中有同名屬性,那麼會產生衝突。

<?php
    trait A1{
       public $a=11;
    }
    trait A2{
       public $a=22;
    }

    class A3{
        use A1,A2;//不允许同名属性
        public function geta(){
            echo $this->a;
        }
    }

    $example=new A3();
  

?>

     b.如果同時引入的多個trait中有同名方法,那麼會產生衝突,有兩種方案解決如A3、A4。

<?php
    trait A1{
       public $a=11;
       public function eat(){
           echo "A1中eat()方法","<br>";
       }
    }
    trait A2{
       public $b=22;
       public function eat(){
        echo "A2中eat()方法","<br>";
      }
    }

    class A3{
        use A1,A2{
          A1::eat insteadOf A2; //A1中的eat替代A2中的eat
        }
    }
    class A4{
        use A1,A2{
            A1::eat insteadOf A2;//A1中的eat替代A2中的eat
            A2::eat as eat2;     //A2中的eat取别名eat2
          }
    }

    $example=new A3();
    $example->eat();
    $example=new A4();
    $example->eat2();
?>

    c.同名覆蓋問題:如果類別中有與引入的trait同名成員,會有不同處理:

  •   屬性:不允許重名,即類別中不允許定義與trait中同名的成員屬性(靜態屬性也是一樣)。

  •  方法:類別覆寫trait。

    d.繼承覆蓋問題:如果類別中在使用trait的同時,也是繼承自父類,而trait中與父類中有同名方法,那麼trait中將覆寫父類別同名方法;如果要存取父類別方法,可以在trait同名方法中使用parent關鍵字存取父類別同名方法。

<?php
    trait Eat{
    public function eat(){
        echo &#39;Eat::eat&#39;;
    }
}
    class Human{
    public function eat(){
        echo &#39;Human::eat&#39;;
    }
}
//子类继承父类同时使用trait
class Man extends Human{
    use Eat;
}

$m = new Man();
$m->eat();
?>

    e.trait自己不能訪問,只是用來給其他類別提供程式碼重複使用的,因此允許類別在使用trait時,使用更高的存取控制權:在as之後,使用目標存取修飾限定符。

<?php
trait Eat{
    private function show(){
        echo &#39;eat&#39;;
    }
}
class Human{
    use Eat{
        show as public eshow;				
        //注意:as是用来设定别名的,虽然没有同名show,但是系统认为show已经存在,所以必须别名,权限的更改的方法不是
        //本尊
    }
}
$h = new Human();
$h->eshow();								//eat
?>

   f.trait中可以使用抽象方法,使用類別必須實作對應抽象方法:使用類別要麼為抽象類,要麼就必須實作抽象方法。

<?php
   trait Eat{
     public function eat();		//抽象方法
   }
   abstract class Human{			
    use Eat;					//抽象类:可以不实现抽象方法
   }

   class Animal{
    use Eat;
    public function eat(){		//具体类:实现抽象方法
        echo &#39;Animal::eat&#39;;	
    }		
}
?>

推薦:php教學,php影片教學

#

以上是總是在重複,氣抖冷,trait何時才能站起來?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn