• php trait


    <?php

    class Base {
    public function sayHello() {
    echo 'Hello ';
    }
    }

    trait SayWorld {
    public function sayHello() {
    parent::sayHello();//先调用父类的sayHello
    echo 'World!<br/>';
    }
    }

    class MyHelloWorld1 extends Base {
    use SayWorld;
    }

    $o = new MyHelloWorld1();
    $o->sayHello();
    echo "<hr>";

     

    echo "为了解决多个 trait 在同一个类中的命名冲突,需要使用 insteadof 操作符来明确指定使用冲突方法中的哪一个<br/>
    在本例中 Talker 使用了 trait A 和 B。由于 A 和 B 有冲突的方法,其定义了使用 trait B 中的 smallTalk 以及 trait A 中的 bigTalk。
    Aliased使用了 as 操作符来定义了 talk 来作为 B 的 bigTalk 的别名。";
    trait A {
    public function smallTalk() {
    echo 'a';
    }
    public function bigTalk() {
    echo 'A';
    }
    }

    trait B {
    public function smallTalk() {
    echo 'b';
    }
    public function bigTalk() {
    echo 'B';
    }
    }

    class Talker {
    use A, B {
    B::smallTalk insteadof A;
    A::bigTalk insteadof B;
    }
    }

    class Alias {
    use A, B {
    B::smallTalk insteadof A;//insteadof 代替
    A::bigTalk insteadof B;
    B::bigTalk as talk;
    }
    }

    $o=new Alias();

    $o->smallTalk();

    $o->bigTalk();

    $o->talk();

     

     

     

    echo "<hr>";

     

     

    echo "修改方法的访问控制
    使用 as 语法还可以用来调整方法的访问控制。<br/>";

    trait Hello_ {
    public function sayHello() {
    echo 'Hello World!<br/>';
    }
    }

    // 修改 sayHello 的访问控制
    class MyClass1 {
    use Hello_{ sayHello as public;}//protected/private
    }

    // 给方法一个改变了访问控制的别名
    // 原版 sayHello 的访问控制则没有发生变化
    class MyClass2 {
    use Hello_ { sayHello as public new_name; }
    }

    $o=new MyClass1();
    $o->sayHello();

    $o=new MyClass2();
    $o->new_name();

     

    echo "<hr>";


    echo "用 trait 来组成 trait 意思是,用N个trait 组成一个trait<br/>";
    trait Hello {
    public function sayHello() {
    echo 'Hello ';
    }
    }

    trait World {
    public function sayWorld() {
    echo 'World!';
    }
    }

    trait HelloWorld {
    use Hello, World;
    }

    class MyHelloWorld {
    use HelloWorld;
    }

    $o = new MyHelloWorld();
    $o->sayHello();
    $o->sayWorld();

    echo "<hr>为了对使用的类施加强制要求,trait 支持抽象方法的使用。";
    trait Hello2 {
    public function sayHelloWorld() {
    echo 'Hello'.$this->getWorld();
    }
    abstract public function getWorld();
    }

    class MyHelloWorld2 {
    private $world;
    use Hello2;
    public function getWorld() {
    return $this->world;
    }
    public function setWorld($val) {
    $this->world = $val;
    }
    }

    echo "<hr>raits 可以被静态成员静态方法定义。<br/>";

    trait Counter {
    public function inc() {
    static $c = 0;
    $c = $c + 1;
    echo "$c ";
    }
    }

    class C1 {
    use Counter;
    }

    class C2 {
    use Counter;
    }

    $o = new C1(); $o->inc(); // echo 1
    $p = new C2(); $p->inc(); // echo 1

    echo "Example #10 静态方法<br/>";

    trait StaticExample {
    public static function doSomething() {
    return 'Doing something';
    }
    }

    class Example {
    use StaticExample;
    }

    Example::doSomething();

     

    echo "Trait 定义了一个属性后,类就不能定义同样名称的属性,否则会产生 fatal error。 有种情况例外:属性是兼容的(同样的访问可见度、初始默认值)。 在 PHP 7.0 之前,属性是兼容的,则会有 E_STRICT 的提醒。

    Example #12 解决冲突";

    trait PropertiesTrait {
    public $same = true;
    public $different = false;
    }

    class PropertiesExample {
    use PropertiesTrait;
    public $same = true; // PHP 7.0.0 后没问题,之前版本是 E_STRICT 提醒
    public $different = true; // 致命错误
    }

  • 相关阅读:
    自动部署基于Maven的war文件到远程Tomcat
    解决Eclipse中新创建的Maven项目不自动创建web.xml文件
    JFreeChart
    hibernate
    hibernate
    hibernate
    hibernate
    Hibernate
    hibernate关联关系映射详解
    Hibernate获取数据java.lang.StackOverflowError
  • 原文地址:https://www.cnblogs.com/nfyx/p/trait.html
Copyright © 2020-2023  润新知