• 周蓬安.blog的博客—强国博客—人民网 2019-05-10
  • 紫光阁中共中央国家机关工作委员会 2019-05-10
  • 感触名家笔下的端午文化吃香粽原来可以这样文艺 2019-05-09
  • 追梦夺冠游行嘲讽詹皇 百万人面前穿订制T恤羞辱他 2019-04-27
  • 《瘟疫传说》:黑死病恐怖 姐弟在绝望中求生 2019-04-10
  • 陕西国防工业职业技术学院百名大学生志愿者敬老院慰问孤寡老人陕西国防工业职业技术学院百名大学生志愿者敬老院慰问-陕西教育新闻 2019-04-08
  • 西藏拉萨:新家园 新生活 2019-04-08
  • 尊重和保障宗教信仰自由的中国实践 2019-04-06
  • 一敬泯恩仇 俄罗斯队主帅这个动作太暖了 2019-03-20
  • 四大名著剧组首次同台忆往事 经典影视剧如何铸就? 2018-12-07
  • “天眼”凝望 探秘宇宙 2018-12-07
  • 0

    PHP Trait 特性的作用

    Posted by 撒得一地 on 2016年7月15日 in PHP笔记
    国外稳定加速器推荐    Express | Vypr

    Trait 是 PHP5.4 中的新特性,是 PHP 多重继承的一种解决方案。例如,需要同时继承两个 Abstract Class, 这将会是件很麻烦的事情,Trait 就是为了解决这个问题。

    简单使用

    首先,当然是声明个 Trait,PHP5.4 增加了 trait 关键字

    trait first_trait {
    	  function first_method() { /* Code Here */ }
    
    	  function second_method() { /* Code Here */ }
    }
    

    同时,如果要在 Class 中使用该 Trait,那么使用 use 关键字

    class first_class {
    	 // 注意这行,声明使用 first_trait
    	 use first_trait;
    }
    
    $obj = new first_class();
    
    // Executing the method from trait
    $obj->first_method(); // valid
    $obj->second_method(); // valid
    

    使用多个 Trait

    在同个 Class 中可以使用多个 Trait

    trait first_trait
    {
    	function first_method() { echo "method1"; }
    }
    
    trait second_trait {
    	 function second_method() { echo "method2"; }
    }
    
    class first_class {
    	 // now using more than one trait
    	 use first_trait, second_trait;
    }
    
    $obj= new first_class();
    // Valid
    
    $obj->first_method(); // Print : method1
    // Valid
    
    $obj->second_method(); // Print : method2
    

    Trait 之间的嵌套

    同时,Trait 之间也可以相互的嵌套,例如

    trait first_trait {
    	  function first_method() { echo "method1"; }
    }
    
    trait second_trait {
    	 use first_trait;
    	 function second_method() { echo "method2"; }
    }
    
    class first_class {
    	 // now using 
    	 use second_trait;
    
    }
    
    $obj= new first_class();
    
    // Valid
    $obj->first_method(); // Print : method1
    
    // Valid
    $obj->second_method(); // Print : method2
    

    Trait 的抽象方法(Abstract Method)

    我们可以在 Trait 中声明需要实现的抽象方法,这样能使使用它的 Class 必须实现它

    trait first_trait {
    	 function first_method() { echo "method1"; }
    	 // 这里可以加入修饰符,说明调用类必须实现它
    	 abstract public function second_method();
    }
    
    class first_method {
    	 use first_trait;
    	 function second_method() {
    	    /* Code Here */
    	 }
    }
    

    Trait 冲突

    多个 Trait 之间同时使用难免会冲突,这需要我们去解决。PHP5.4 从语法方面带入了相关 的关键字语法:insteadof 以及 as ,用法参见

    trait first_trait {
    	  function first_function() { 
    	      echo "From First Trait";
    	  }
    }
    
    trait second_trait {
    	  // 这里的名称和 first_trait 一样,会有冲突
    	  function first_function() { 
    	    echo "From Second Trait";
    	  }
    }
    
    class first_class {
    	 use first_trait, second_trait {
    	     // 在这里声明使用 first_trait 的 first_function 替换
    	     // second_trait 中声明的
    	     first_trait::first_function insteadof second_trait;
    	 }
    }  
    
    $obj = new first_class();
    // Output: From First Trait
    $obj->first_function();
    

    需要注意的几点

    上面就是些 Trait 比较基本的使用了,更详细的可以参考官方手册。这里总结下注意的几 点:

    Trait 会覆盖调用类继承的父类方法
    Trait 无法如 Class 一样使用 new 实例化
    单个 Trait 可由多个 Trait 组成
    在单个 Class 中,可以使用多个 Trait
    Trait 支持修饰词(modifiers),例如 final、static、abstract
    我们能使用 insteadof 以及 as 操作符解决 Trait 之间的冲突

    一些看法

    坦白讲,我第一眼看到 Trait 对它并没有任何好感。PHP5 以来带来的新特性已经足够得 多,而且让开发者们有点应接不暇。

    同时,Trait 更像是程序员的“语法糖”,然而它提供便利的同时可能会造成巨大的隐患。 例如 Trait 能够调用类中的成员:

    	trait Hello {
    	    public function sayHelloWorld() {
    	        echo 'Hello'.$this->getWorld();
    	    }
    
    	    abstract public function getWorld();
    	}
    
    	class MyHelloWorld {
    	    private $world;
    	    use Hello;
    
    	    public function getWorld() {
    	        return $this->world;
    	    }
    
    	    public function setWorld($val) {
    	        $this->world = $val;
    	    }
    	}
    

    同时,针对类中已经实现的方法,Trait 没有效果

    	trait HelloWorld {
    	    public function sayHello() {
    	        echo 'Hello World!';
    	    }
    	}
    
    	class TheWorldIsNotEnough {
    	    use HelloWorld;
    	    public function sayHello() {
    	        echo 'Hello Universe!';
    	    }
    	}
    
    	$o = new TheWorldIsNotEnough();
    	$o->sayHello(); // echos Hello Universe!
    

    那么 Trait 的出现是为何呢?有哥们的回答比较有意思,但不无道理:

    因为php没有javascript作用域链的机制,所以无法把function bind到class里面,曾经以为php 5.3的闭包可以做这个事,最后才发觉作用域的设计不允许这么干但话说回来,拿 interface 和 Trait 类比,显然 Trait 有更多方便的地方(虽然 两者不能完全相互替代)。

    不过很显然 Trait 目前还处于测试阶段,它的未来相比其他 PHP5 新推来的特性还有 更多让人观望的地方,但或许这特性能改变 PHP5 未来继承的方式。

    因为,我个人坚信 PHP 的作用链设计迟早会改得“更像 JavaScript”,即便这事情会在遥远的 PHP6 。

    上一篇:

    下一篇:

    相关推荐

    发表评论

    电子邮件地址不会被公开。 必填项已用*标注

    7 + 4 = ?

    网站地图|广东快乐10分开奖直播

    Copyright © 2015-2019 广东快乐10分开奖直播 All rights reserved.
    闽ICP备15015576号-1,版权所有?psz.

  • 周蓬安.blog的博客—强国博客—人民网 2019-05-10
  • 紫光阁中共中央国家机关工作委员会 2019-05-10
  • 感触名家笔下的端午文化吃香粽原来可以这样文艺 2019-05-09
  • 追梦夺冠游行嘲讽詹皇 百万人面前穿订制T恤羞辱他 2019-04-27
  • 《瘟疫传说》:黑死病恐怖 姐弟在绝望中求生 2019-04-10
  • 陕西国防工业职业技术学院百名大学生志愿者敬老院慰问孤寡老人陕西国防工业职业技术学院百名大学生志愿者敬老院慰问-陕西教育新闻 2019-04-08
  • 西藏拉萨:新家园 新生活 2019-04-08
  • 尊重和保障宗教信仰自由的中国实践 2019-04-06
  • 一敬泯恩仇 俄罗斯队主帅这个动作太暖了 2019-03-20
  • 四大名著剧组首次同台忆往事 经典影视剧如何铸就? 2018-12-07
  • “天眼”凝望 探秘宇宙 2018-12-07
  • 三亚朝阳社区中国福利彩票销售点 秒速时时彩ios 北京多乐彩票骗局 大发娱乐城 中国竞彩网竞猜冠亚军 足球竞彩比分直播 燕赵风采20选5开奖 高尔夫赌场德州扑克 nba让分胜负巧 赛车北京pk10历史记录 七星彩走势图表近500期 安徽福利彩票发行中心 秒速时时彩计划网 新时时彩倍投计算器 重庆时时彩骗局 今日3d试机号