精华内容
下载资源
问答
  • Trait

    2021-03-30 11:36:47
    Trait和类相似,支持定义方法和属性,但不是类,不支持定义构造函数,因而不能实例化,只能被其他类使用,要在一个类中使用 Trait,可以通过use 关键字引入,然后就可以在类方法中直接使用 trait 中定义的方法了...

    作用:解决代码复用问题,解决单一继承问题

    Trait和类相似,支持定义方法和属性,但不是类,不支持定义构造函数,因而不能实例化,只能被其他类使用,要在一个类中使用 Trait,可以通过use 关键字引入,然后就可以在类方法中直接使用 trait 中定义的方法了(Trait支持属性和方法以及可见性设置(private、protected、public),并且即使是 private 级别的方法和属性,依然可以在使用类中调用

    与普通类的异同

    • 相同点

      trait 能够像普通的类一样定义属性,方法(包含抽象的、静态的)
      trait 引入到基类里面,其子类里面也能访问 trait 里面的属性和方法。
      
    • 不用点

      trait 不用实例化就能访问定义的普通方法以及属性。
      trait 里面不能定义构造函数。
      

    实践

    <?php
    Trait TraitOne {
        public $propertyOne = 'argumentOne';
    
        public function sayHello()
        {
            return 'My trait one';
        }
    }
    
    Trait TraitTwo {
        public function sayHello()
        {
            return 'My Trait Two';
        }
    }
    
    class MyClass {
    
        use TraitOne, TraitTwo {
    
            TraitTwo::sayHello insteadof TraitOne;  //指定要使用的trait
    
            Traittwo::sayHello as twoSayHello; //同方法名的trait设置别名
    
        }
    
        public function traitMethodValue()
        {
            return $this->twoSayHello();   //调用trait别名方法
        }
    }
    
    $myClass = new MyClass();
    echo $myClass->twoSayHello();
    
    class MyClassSon extends MYClass {
    
    }
    
    $myClass = new MyClassSon();
    echo $myClass->twoSayHello(); //traits方法可以被继承
    

    trait访问权限控制

    trait Log{
    	public function save(){
        	return __METHOD__;
        }
    }
    
    trait Comment{
    	public function save(){
        	return __METHOD__;
        }
    }
    
    class Topic{
    	use Log,Commenr{
        	Log::save insteadof Comment; //当trait里面的方法重名时可用这种方式替换
          	Log::save as protect;//将此方法限制只能在本类进行使用
          	Comment::save as send; //如果非要使用Comment里面的save方法 可用别名方式替代
        }
    }
    
    $topic=new Topic();
    echo $topic->save();
    
    展开全文
  • trait

    2021-03-06 23:44:36
    Trait 关键字 由来: PHP 是一门单继承的语言。为了实现多继承的效果, 在 5.4 以后引入了新的关键字 Trait 来解决多继承问题。 作用: 以一种优雅的方式解决了多继承问题,提升了代码的复用性。 用法: 使用 Trait ...

    Trait 关键字

    介绍:

    1. PHP 是一门单继承的语言。为了实现多继承的效果, 在 5.4 以后引入了新的关键字 Trait 来解决多继承问题。

    作用:

    1. 以一种优雅的方式解决了多继承问题,提升了代码的复用性。

    特点:

    1. 创建方式类似于类,只需要把创建类时的 Class关键字 替换成 trait 就可了
    2. 不允许被实例化
    3. 在类中使用 use 来导入就可使用
    4. 执行优先级: 类方法 > trait 方法 > 基类方法

    例子:

    <?php
    
    class  Base
    {
        public function hello()
        {
            echo 'method hello from class Base' . PHP_EOL;
        }
    }
    
    trait  Hello
    {
    
        public function hello()
        {
            echo 'method hello from Trait Hello!' . PHP_EOL;
        }
    
        public function hi()
        {
            echo 'method hi from Trait Hello' . PHP_EOL;
        }
    
        abstract public function getValue();
    
        static public function staticMethod()
        {
            echo 'static method staticMethod from Trait Hello' . PHP_EOL;
        }
    
        public function staticValue()
        {
            static $value;
            $value++;
            echo "$value" . PHP_EOL;
        }
    }
    
    trait Hi
    {
        public function hello()
        {
            parent:: hello();
            echo 'method hello from Trait Hi!' . PHP_EOL;
        }
    
        public function hi()
        {
            echo 'method hi from Trait Hi' . PHP_EOL;
        }
    }
    
    trait HelloHi
    {
        use  Hello, Hi {
            Hello::hello insteadof Hi;
            Hi::hi insteadof Hello;
        }
    }
    
    
    class  MyNew extends Base
    {
        use HelloHi;
    
        private $value = 'class MyNew' . PHP_EOL;
    
        public function hi()
        {
            echo 'method hi from class MyNew' . PHP_EOL;
        }
    
        public function getValue()
        {
            return $this->value;
        }
    
    }
    
    $obj = new MyNew ();
    
    $obj->hello();
    //输出:'method hello from Trait Hello!'
    //优先级顺序:trait中的方法又覆盖了基类中的方法
    
    $obj->hi();
    //输出:'method hi from class MyNew'
    //优先级顺序:当前类中的方法会覆盖 trait 方法
    
    MyNew::staticMethod();
    //输出:'static method staticMethod from Trait Hello'
    //静态方法:trait中可以定义静态方法
    
    echo $obj->getValue();
    //输出:'class MyNew'
    //抽象成员:trait中可以使用抽象方法
    
    $objOther = new MyNew();
    $obj->staticValue();
    //输出:1
    
    
    展开全文
  • PHP Trait

    2018-09-29 21:53:54
    PHP Trait

    PHP5.4实现了一种代码复用的方法称为Trait。Trait为了减少单继承语言的限制,能够自由地在不同层次结构内独立的类中复用方法,Trait和Class组合的语义定义了一种减少复杂性的方式,避免传统多继承和 Mixin 类相关典型问题。无法通过 trait 自身来实例化。一个类要应用trait需要使用use关键字,一个类可以应用多个trait,只需要在use关键字后用逗号分隔多个trait。trait中也可以应用其他的trait。

    <?php
    trait a{
        function getA(){
            return "a";
        }
    }
    trait b{
        function getB(){
            return "b";
        }
    }
    class Test{
        use a,b;
    }
    $test=new Test();
    echo $test->getA()."\n";
    echo $test->getB()."\n";
    
    trait c{
        use a,b;
    }
    class Test2{
        use c;
    }
    $test=new Test2();
    echo $test->getA()."\n";
    echo $test->getB()."\n";
    ?>

    如果trait和class中存在相同的成员,则优先级规则为,当前类的成员->trait的成员->继承的成员。

    <?php
    trait a{
        function getA(){
            parent::getA();
            echo "a in trait\n";
        }
    }
    class Base{
        function getA(){
            echo "a in Base\n";
        }
    }
    class Test extends Base{
        use a;
    }
    class Test2 extends Base{
        use a;
        function getA(){
            echo "a in Test2\n";
        }
    }
    $test=new Test();
    $test->getA();
    
    $test2=new Test2();
    $test2->getA();
    ?>

    在应用多个trait时,如果插入了同名的方法,则需要解决冲突,否则会产生致命错误。解决冲突可以使用insteadof关键字来指明使用哪一个方法。还可以通过as关键字为某个方法引入别名,as关键字还可以调整方法的访问控制。

    <?php
    trait A {
        public function printLower() {
            echo 'a';
        }
        public function printUpper() {
            echo 'A';
        }
    }
    
    trait B {
        public function printLower() {
            echo 'b';
        }
        public function printUpper() {
            echo 'B';
        }
        public function testAccess(){
            
        }
    }
    
    class Test {
        use A, B {
            B::printLower insteadof A;
            A::printUpper insteadof B;
            B::printUpper as private upper;
            testAccess as protected;
        }
    }
    
    $test=new Test();
    $test->printLower();
    $test->printUpper();
    //$test->upper();
    //$test->testAccess();
    ?>

    trait还支持抽象方法,应用trait的类需要实现抽象方法,否则会产生致命错误。trait还支持静态成员。

    <?php
    trait a{
        function lower(){
            return "a";
        }
        abstract function upper();
        public static function foo(){
            echo "static function foo\n";
        }
    }
    class Test{
        use a;
        function upper(){
            return "A";
        }
    }
    $t=new Test();
    echo $t->lower()."\n";
    echo $t->upper()."\n";
    Test::foo();
    ?>

    trait中可以定义属性,但是应用trait的类不能定义与之同名的属性,否则会产生致命错误,除非属性是兼容的,即访问控制和初始默认值都相同。PHP7.0之前即使属性兼容也会有E_STRICT的提醒。

    <?php
    trait a{
        public $var="a";
        public $diff1="a";
        public $diff2="a";
    }
    class Test{
        use a;
        public $var="a";
        //public $diff1="b";
        //protected $diff2="a";
    }
    ?>

     

    展开全文
  • php trait

    2021-03-18 15:38:27
    用法:通过在类中使用use 关键字,声明要组合的Trait名称,具体的Trait的声明使用Trait关键词,Trait不能实例化 如下代码实例: <?php trait Dog{ public $name="dog"; public function bark(){ echo "This ...

    php从以前到现在一直都是单继承的语言,无法同时从两个基类中继承属性和方法,为了解决这个问题,php出了Trait这个特性创建方式

    用法:通过在类中使用use 关键字,声明要组合的Trait名称,具体的Trait的声明使用Trait关键词,Trait不能实例化

    如下代码实例:

    <?php
    trait Dog{
        public $name="dog";
        public function bark(){
            echo "This is dog";
        }
    }
    class Animal{
        public function eat(){
            echo "This is animal eat";
        }
    }
    class Cat extends Animal{
        use Dog;
        public function drive(){
            echo "This is cat drive";
        }
    }
    $cat = new Cat();
    $cat->drive();
    echo "<br/>";
    $cat->eat();
    echo "<br/>";
    $cat->bark();
    ?>

    将会如下输出

    再测试Trait、基类和本类对同名属性或方法的处理,如下代码

    <?php
    trait Dog{
        public $name="dog";
        public function drive(){
            echo "This is dog drive";
        }
        public function eat(){
            echo "This is dog eat";
        }
    }
    
    class Animal{
        public function drive(){
            echo "This is animal drive";
        }
        public function eat(){
            echo "This is animal eat";
        }
    }
    
    class Cat extends Animal{
        use Dog;
        public function drive(){
            echo "This is cat drive";
        }
    }
    $cat = new Cat();
    $cat->drive();
    echo "<br/>";
    $cat->eat();
    
    ?>

    如下显示

    所以:Trait中的方法会覆盖基类中的同名方法,而本类会覆盖Trait中同名方法
    注意点:当trait定义了属性后,类就不能定义同样名称的属性,否则会产生 fatal error,除非是设置成相同可见度、相同默认值。不过在php7之前,即使这样设置,还是会产生E_STRICT 的提醒

    一个类可以组合多个Trait,通过逗号相隔,如下

    use trait1,trait2

    当不同的trait中,却有着同名的方法或属性,会产生冲突,可以使用insteadof或 as进行解决,insteadof 是进行替代,而as是给它取别名
    如下实例:

    <?php
    trait trait1{
        public function eat(){
            echo "This is trait1 eat";
        }
        public function drive(){
            echo "This is trait1 drive";
        }
    }
    trait trait2{
        public function eat(){
            echo "This is trait2 eat";
        }
        public function drive(){
            echo "This is trait2 drive";
        }
    }
    class cat{
        use trait1,trait2{
            trait1::eat insteadof trait2;
            trait1::drive insteadof trait2;
        }
    }
    class dog{
        use trait1,trait2{
            trait1::eat insteadof trait2;
            trait1::drive insteadof trait2;
            trait2::eat as eaten;
            trait2::drive as driven;
        }
    }
    $cat = new cat();
    $cat->eat();
    echo "<br/>";
    $cat->drive();
    echo "<br/>";
    echo "<br/>";
    echo "<br/>";
    $dog = new dog();
    $dog->eat();
    echo "<br/>";
    $dog->drive();
    echo "<br/>";
    $dog->eaten();
    echo "<br/>";
    $dog->driven();
    ?>

    输出如下

     

    as 还可以修改方法的访问控制

    <?php
    trait Animal{
        public function eat(){
            echo "This is Animal eat";
        }
    }
    
    class Dog{
        use Animal{
            eat as protected;
        }
    }
    class Cat{
        use Animal{
            Animal::eat as private eaten;
        }
    }
    $dog = new Dog();
    $dog->eat();//报错,因为已经把eat改成了保护
    
    $cat = new Cat();
    $cat->eat();//正常运行,不会修改原先的访问控制
    $cat->eaten();//报错,已经改成了私有的访问控制
    ?>

    Trait也可以互相组合,还可以使用抽象方法,静态属性,静态方法等,实例如下

    <?php
    trait Cat{
        public function eat(){
            echo "This is Cat eat";
        }
    }
    
    trait Dog{
        use Cat;
        public function drive(){
            echo "This is Dog drive";
        }
        abstract public function getName();
        
        public function test(){
            static $num=0;
            $num++;
            echo $num;
        }
        
        public static function say(){
            echo "This is Dog say";
        }
    }
    class animal{
        use Dog;
        public function getName(){
            echo "This is animal name";
        }
    }
    
    $animal = new animal();
    $animal->getName();
    echo "<br/>";
    $animal->eat();
    echo "<br/>";
    $animal->drive();
    echo "<br/>";
    $animal::say();
    echo "<br/>";
    $animal->test();
    echo "<br/>";
    $animal->test();
    ?>
    

    输出如下

     

    展开全文
  • 那么,这些所谓的Trait是什么呢?Trait就是包含方法的类。这个Trait可以与许多类共享。使用这个trait的所有类都可以使用trait方法。为什么你可能想要使用一个Trait?可能有很多原因使你希望使用某个特性。例...
  • trait使用

    2018-12-15 15:28:28
    1、php单继承模式,trait突破了单继承,...//trait 不能实例化的类 trait Demo1 { public function hello1(){ return __METHOD__; } } trait Demo2 { public function hello2(){ return __METHOD__; } } cl...
  • Trait讲解

    2018-12-28 22:36:00
    <?... /** * Trait解决PHP单继承的一种方法,使开发... * Trait不是类,不能被继承,所以不能再Trait中不能声明抽象方法 * Trait中无法声明常量 * ThinkPHP中Trait有应用 */ //声明一个Trait trait Nam...
  • trait介绍

    2019-07-16 18:17:00
    手册中关于trait的介绍: 自 PHP 5.4.0 起,PHP 实现了一种代码复用的方法,称为 traitTrait 是为类似 PHP 的单继承语言而准备的一种代码复用机制。Trait 为了减少单继承语言的限制,使开发人员能够自由地在...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 22,983
精华内容 9,193
关键字:

trait