首页 > 代码库 > php trait

php trait

学习: yf lr

 

 

Trait, 代码复用, 变相的多继承

1 方法重名, 优先级: 当前类>trait>基类

2 多个Trait的时候, 方法重名, 可以使用insteadof筛选不需要的trait

3 trait方法重命名后, 两种调用方式都存在,不能解决命名冲突

4 重命名可以设置访问权限,但是之前的访问权限没有改变

5 可以将多个trait组合成一个trait

6 trait可以包含抽象方法,在使用的时候需要重新实现

7 trait可以被静态成员静态方法定义

8 如果trait定义了一个熟悉,那当前类不能再定义同样名称的属性,如果该属性在类中和trait里面的权限和初始值是一样的,错误是E_STRICT,否则是一个致命错误

9 trait的use和namespace的use不一样的, namespace的use使用的的命名空间或命名空间里面的方法, use使用当前空间的一个trait

10 __TRAIT__获取当前use的trait名称

11 trait的方法可以当做普通类的静态方法调用

<?php 

trait TraitClass{
    function dos(){
        echo "trait dos\n";
    }
    function not(){
        echo "trait not\n";
    }
    function gg(){
        echo "trait gg\n";
    }
}

class Father{
    function dos(){
        echo "father dos\n";
    }
    function not(){
        echo "father not\n";
    }
}

class Son extends Father{
    use TraitClass;
    function not(){
        echo "son not\n";
    }
}

//同名方法优先级 当前类>trait>基类
$son = new Son();
$son->not();//输出 son not  
$son->dos();//输出 trait dos  
echo "\n";
trait Trait1{
    function say(){
        echo "trait1 say\n";
    }
    function run(){
        echo "trait1 run\n";
    }
}
trait Trait2{
    function say(){
        echo "trait2 say\n";
    }
    function run(){
        echo "trait2 run\n";
    }
}
trait Trait3{
    function say(){
        echo "trait3 say\n";
    }
    function run(){
        echo "trait3 run\n";
    }
}
class Son1{
    use Trait1,Trait2,Trait3{
        Trait1::say insteadof Trait2,Trait3;
        Trait2::run insteadof Trait1,Trait3;
        Trait3::run as trait3run;
        Trait1::say as trait1say;
        Trait1::say as private trait1say_;
    } 
}
//多个trait,并方法重命,可以使用insteadof排除不使用的选项,这里确定比较奇怪,如果很多的话,不说很麻烦么,用insteadof来指定使用哪一个不就好了么
//trait重命名之后,不能解决冲突,两种调用都会保留下来
$son1 = new Son1();
$son1->say();//输出 trait1 say
$son1->run();//输出 trait2 run
$son1->trait3run();//输出 trait3 run
$son1->trait1say();//输出 trait1 say
//$son1->trait1say_();//致命错误  私有方法无法访问,
//重命名可以设置访问权限,但是之前的访问权限没有改变
echo "\n";

trait Trait4{
    function dos(){
        echo "trait4 dos\n";
    }
}
trait Trait5{
    function run(){
        echo "trait5 run\n";
    }
}
trait Trait6{
    use Trait4,Trait5;
}
class Son2{
    use Trait6;
}
//可以将多个trait组合成一个trait
$son2 = new Son2();
$son2->dos();
$son2->run();
echo "\n";

trait Trait7{
    abstract function getName();
}
trait Trait8{
    public $same = true;
    public $different = false;
    static $c=0;
    public static function inc(){
        self::$c++;
        echo self::$c."\n";
    }
}
class Son3{
    use Trait7;
    function getName(){
        echo "new getName\n";
    }
}
class Son4{
    use Trait8;
    public $same = true;
    public $different = false;//同样的权限和初始值 
}
class Son5{
    use Trait8;
    public $same = true;
    //public $different = true;//致命错误
}
//trait可以包含抽象方法,在使用的时候需要重新实现
//trait可以被静态成员静态方法定义
//如果trait定义了一个熟悉,那当前类不能再定义同样名称的属性,如果该属性在类中和trait里面的权限和初始值是一样的,错误是E_STRICT,否则是一个致命错误
$son3 = new Son3();
$son3->getName();// 输出 new getName
$son4 = new Son4();
$son4::inc();//输出 1
$son5 = new Son5();
$son5::inc();//输出 1
echo "\n";

 

<?php

namespace Blog\Article;
use Blog\Money;//使用Blog\Money命名空间

  

<?php

namespace Blog\Article;
class Son{
    use Blog\Money;//使用trait 找的是Blog\Article\Blog\Money
}

  

<?php

trait Trait1{
    function run(){
        echo "trait1 run\n";
    }
}
Trait1::run();
//trait的方法可以当做普通类的静态方法调用

 

php trait