84669 orang belajar
152542 orang belajar
20005 orang belajar
5487 orang belajar
7821 orang belajar
359900 orang belajar
3350 orang belajar
180660 orang belajar
48569 orang belajar
18603 orang belajar
40936 orang belajar
1549 orang belajar
1183 orang belajar
32909 orang belajar
看过了一些trait的介绍,也在框架中看到了。但是感觉trait做的事情,用interface是不是也能做呢?
个人感觉每个trait实现的功能都非常集中,也非常轻量,这个很赞,但是相对的有些class可能要同时用好几个trait,而且假如同时继承了类,实现了接口,并且其中包含覆盖,那理清这个类的关系感觉会很困难,这是我最困惑的地方,当然也可能是我技术还不够。
但是既然出了这个语法,肯定还是有他的道理的,所以就想问一下,项目中使用trait的意义是什么呢?
欢迎选择我的课程,让我们一起见证您的进步~~
有不少目的,我相信其他的答案会从各个角度提及。
我所知道的一个重要目的是:方便代码生成器的工作。
如果一个类的部分代码是生成器产生的,部分代码是自己写的,那么我们肯定希望生成器产生的代码在trait里,我们自己写的代码引用这个trait。这样如果生成器需要重新运行,自写的代码就无需任何变化。
trait
这一点用继承也许也能做到,但PHP没有多继承。同时引用多个生成器产生的代码,只能依赖trait。
这一点你可以看一下 C# 的“部分类”(partial class)。在目的上是很相似的。
trait和interface恰好相反,interface关心的是接口,把实现丢给其他人,而trait完全不关心接口(约定),只提供实现。不那么准确地说的话,trait = abstract class - interface,提供了另一个维度的灵活性
一个常见的应用场景是为接口提供“默认实现”,比如经典的\Psr\Log\LoggerInterface接口,有一堆方法(critical/emerg/info/debug)等等,但实际实现的时候,大家都会把这些方法都转发到log()方法里去,所以PSR提供了\Psr\Log\LoggerTrait,这样既保持了接口的完整(每个错误等级都有独立的方法),又方便了实现者
\Psr\Log\LoggerInterface
log()
\Psr\Log\LoggerTrait
你可以这么理解 1、trait 用来复用代码的2、解决了 php 不能多继承的问题(多继承也会产生问题,这里不展开)3、使用 trait的类,跟 trait 本身是可以没有任何关系的
php
.......
trait 里面定义了实现interface 只是声明这两个还是有区别的
interface
......
PHP和Java等大多数面向对象的语言一样是单继承,既一个类只能继承于一个父类。虽然单继承是公认使代码清晰准确的方式,但有时候多继承也有自己的优势。trait的出现就是一种解决需要多继承场景的方式。多继承的好处就是让一个类继承多个父类的功能,虽然这违反了类单一职责原则,但是在某些场合下,一些小功能使用多继承是最合适不过的。比如Laravel中定义了一个宏trait,只是很简单的让类实现一些类似C宏定义的方法,因为这其中含有一些实体方法和属性,所以通过interface定义是不能实现的,而需要使用这个功能的类又有可能已经继承于其他类,所以通过abstract class定义也是不能实现的,所以这种场合下trait就能体现它的优势了。
PHP
Java
Laravel
C
abstract class
这篇博客中有讲到哦,可以看看http://overtrue.me/articles/2016/04/about-php-trait.html
在解决多继承的代码中用的较多
减少复制粘贴造成的维护不便问题
通俗一点,就是能把重复的方法拆分到一个文件,通过 use 引入以达到代码复用的目的
看了一下trait的定义,并测试了一下。感觉是把设计模式里面的适配器模型做到语言层面了。多继承的语言没用过,不敢做评论。就看到的几个实例,都可以使用适配器+接口实现,只是实现起来比较绕,没有trait这么清晰。
个人理解:在一个类中使用Trait,就相当于这个类也有了Trait中定义的属性和方法。Traits的使用场景是如果多个类都要用到同样的属性或者方法,这个时候使用Traits可以方便的给类增加这些属性或方法,而不用每个类都去继承一个类,如果说继承类是竖向扩展一个类,那么Traits是横向扩展一个类,从而实现代码复用。
Laravel中triat的使用:http://blog.tanteng.me/2015/12/laravel-trait/
有不少目的,我相信其他的答案会从各个角度提及。
我所知道的一个重要目的是:方便代码生成器的工作。
如果一个类的部分代码是生成器产生的,部分代码是自己写的,那么我们肯定希望生成器产生的代码在
trait
里,我们自己写的代码引用这个trait
。这样如果生成器需要重新运行,自写的代码就无需任何变化。这一点用继承也许也能做到,但PHP没有多继承。同时引用多个生成器产生的代码,只能依赖
trait
。这一点你可以看一下 C# 的“部分类”(partial class)。在目的上是很相似的。
trait和interface恰好相反,interface关心的是接口,把实现丢给其他人,而trait完全不关心接口(约定),只提供实现。不那么准确地说的话,trait = abstract class - interface,提供了另一个维度的灵活性
一个常见的应用场景是为接口提供“默认实现”,比如经典的
\Psr\Log\LoggerInterface
接口,有一堆方法(critical/emerg/info/debug)等等,但实际实现的时候,大家都会把这些方法都转发到log()
方法里去,所以PSR提供了\Psr\Log\LoggerTrait
,这样既保持了接口的完整(每个错误等级都有独立的方法),又方便了实现者你可以这么理解
1、
trait
用来复用代码的2、解决了
php
不能多继承的问题(多继承也会产生问题,这里不展开)3、使用
trait
的类,跟trait
本身是可以没有任何关系的.......
trait
里面定义了实现interface
只是声明这两个还是有区别的
......
PHP
和Java
等大多数面向对象的语言一样是单继承,既一个类只能继承于一个父类。虽然单继承是公认使代码清晰准确的方式,但有时候多继承也有自己的优势。trait
的出现就是一种解决需要多继承场景的方式。多继承的好处就是让一个类继承多个父类的功能,虽然这违反了类单一职责原则,但是在某些场合下,一些小功能使用多继承是最合适不过的。比如Laravel
中定义了一个宏trait
,只是很简单的让类实现一些类似C
宏定义的方法,因为这其中含有一些实体方法和属性,所以通过interface
定义是不能实现的,而需要使用这个功能的类又有可能已经继承于其他类,所以通过abstract class
定义也是不能实现的,所以这种场合下trait
就能体现它的优势了。这篇博客中有讲到哦,可以看看
http://overtrue.me/articles/2016/04/about-php-trait.html
在解决多继承的代码中用的较多
减少复制粘贴造成的维护不便问题
通俗一点,就是能把重复的方法拆分到一个文件,通过 use 引入以达到代码复用的目的
看了一下trait的定义,并测试了一下。感觉是把设计模式里面的适配器模型做到语言层面了。
多继承的语言没用过,不敢做评论。就看到的几个实例,都可以使用适配器+接口实现,只是实现起来比较绕,没有trait这么清晰。
个人理解:在一个类中使用Trait,就相当于这个类也有了Trait中定义的属性和方法。Traits的使用场景是如果多个类都要用到同样的属性或者方法,这个时候使用Traits可以方便的给类增加这些属性或方法,而不用每个类都去继承一个类,如果说继承类是竖向扩展一个类,那么Traits是横向扩展一个类,从而实现代码复用。
Laravel中triat的使用:
http://blog.tanteng.me/2015/12/laravel-trait/