当前位置 博文首页 > 文章内容

    总是在重复,气抖冷,trait何时才能站起来?

    作者:shunshunshun18 栏目:未分类 时间:2021-03-05 10:45:55

    本站于2023年9月4日。收到“大连君*****咨询有限公司”通知
    说我们IIS7站长博客,有一篇博文用了他们的图片。
    要求我们给他们一张图片6000元。要不然法院告我们

    为避免不必要的麻烦,IIS7站长博客,全站内容图片下架、并积极应诉
    博文内容全部不再显示,请需要相关资讯的站长朋友到必应搜索。谢谢!

    另祝:版权碰瓷诈骗团伙,早日弃暗投明。

    相关新闻:借版权之名、行诈骗之实,周某因犯诈骗罪被判处有期徒刑十一年六个月

    叹!百花齐放的时代,渐行渐远!



    类中的某些成员如何才能被其他类使用呢?使用继承的话,这继承链也太长了,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 'Eat::eat';
        }
    }
        class Human{
        public function eat(){
            echo 'Human::eat';
        }
    }
    //子类继承父类同时使用trait
    class Man extends Human{
        use Eat;
    }
    
    $m = new Man();
    $m->eat();
    ?>

    e.trait自己不能访问,只是用来给其他类提供代码复用的,因此允许类在使用trait时更高里面方法的访问控制权:在as之后,使用目标访问修饰限定符。

    <?php
    trait Eat{
        private function show(){
            echo 'eat';
        }
    }
    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 'Animal::eat';	
        }		
    }
    ?>

    推荐:,