zoukankan      html  css  js  c++  java
  • 解决php的单继承问题,实现php的多继承,trait的使用

      自 PHP 5.4.0 起,PHP 实现了一种代码复用的方法,称为 trait。

      Trait 是为类似 PHP 的单继承语言而准备的一种代码复用机制。Trait 为了减少单继承语言的限制,使开发人员能够自由地在不同层次结构内独立的类中复用 method。Trait 和 Class 组合的语义定义了一种减少复杂性的方式,避免传统多继承和 Mixin 类相关典型问题。

      Trait 和 Class 相似,但仅仅旨在用细粒度和一致的方式来组合功能。 无法通过 trait 自身来实例化。它为传统继承增加了水平特性的组合;也就是说,应用的几个 Class 之间不需要继承。

      Trait的优先级:

      从基类继承的成员会被 trait 插入的成员所覆盖。优先顺序是来自当前类的成员覆盖了 trait 的方法,而 trait 则覆盖了被继承的方法。

    <?php
    class Base {
        public function sayHello() {
            echo 'Hello ';
        }
    }
    
    trait SayWorld {
        public function sayHello() {
            parent::sayHello();
            echo 'World!';
        }
    }
    
    class MyHelloWorld extends Base {
        use SayWorld;
    }
    
    $o = new MyHelloWorld();
    $o->sayHello();
    ?>
    
    // 以上例程会输出:
    
    // Hello World!

      需要注意的是,多个Trait之间同时使用难免会发生冲突。PHP 5.4从语法方面带入了相关的关键字语法“insteadof”。

      为了对使用的类施加强制要求,Trait支持抽象方法的使用。如果在 Trait 中声明需要实现的抽象方法,这样就使得使用它的类必须先实现它,就像继承抽象类,必须实现类中的抽象方法一样。

      以下示例中演示了trait的多种使用方法:在抽象方法中使用、多继承和方法冲突。

    <?php
    
    //定义第一个 trait 类
    trait DemoTraitOne{
        function Method(){
            echo "这是 TraitOne 中 Method() 的方法<br>";
        }
    }
    
    //定义第二个 trait 类
    trait DemoTraitTwo{
        function Method(){
            echo "这是 TraitTwo 中 MethodTwo() 的方法<br>";
        }
    }
    
    //定义了一个由 abstract 修饰的 trait 类中的方法,实例化时必须实现该方法
    trait DemoTraitThree{
        abstract public function MethodThree();
    }
    
    class DemoClass{
        
        // ①trait解决php的多继承问题,用 use 混入trait 定义的父类
        use DemoTraitOne, DemoTraitTwo, DemoTraitThree{
            
            // ②下面一行代码示例中 insteadof 关键字解决方法冲突
            // 在这里声明由 DemoTraitOne 的 Method() 方法替换
            DemoTraitOne::Method insteadof DemoTraitTwo;
        }
        
        // ③用 abstract 修饰的 trait 要实现抽象类中的方法
        function MethodThree(){
            echo "实现了MethodThree()方法。<br>";
        }
    }
    
    $obj = new DemoClass;
    $obj->Method();
    $obj->MethodThree();
    
    //以上代码会输出:
    //这是 TraitOne 中 Method() 的方法
    //实现了MethodThree()方法。

      Trait会覆盖调用类继承的父类方法。

    从基类继承的成员被Trait插入的成员所覆盖。优先顺序是:来自当前类的成员覆盖了Trait的方法,而Trait则覆盖了被继承的方法。

    1. Trait不能像类一样使用new实例化对象。
    2. 单个Trait可由多个Trait组成。
    3. 在单个类中,用use引入Trait,可以引入多个。
    4. Trait支持修饰词,例如final、static、abstract。
    5. 可以使用insteadof及as操作符解决Trait之间的冲突。
    6. 使用as语法还可以用来调整方法的访问控制。
    7. 更多使用方法请参考php文档。
  • 相关阅读:
    HDU3336 Count the string —— KMP next数组
    CodeForces
    51Nod 1627 瞬间移动 —— 组合数学
    51Nod 1158 全是1的最大子矩阵 —— 预处理 + 暴力枚举 or 单调栈
    51Nod 1225 余数之和 —— 分区枚举
    51Nod 1084 矩阵取数问题 V2 —— 最小费用最大流 or 多线程DP
    51Nod 机器人走方格 V3 —— 卡特兰数、Lucas定理
    51Nod XOR key —— 区间最大异或值 可持久化字典树
    HDU4825 Xor Sum —— Trie树
    51Nod 1515 明辨是非 —— 并查集 + 启发式合并
  • 原文地址:https://www.cnblogs.com/qingsong/p/13170274.html
Copyright © 2011-2022 走看看