PHP之Trait详解
<div class="Post-RichTextContainer"><div class="RichText ztext Post-RichText">
<blockquote>php从以前到现在一直都是单继承的语言,无法同时从两个基类中继承属性和方法,为了解决这个问题,php出了Trait这个特性</blockquote>
<p>用法:通过在类中使用use 关键字,声明要组合的Trait名称,具体的Trait的声明使用Trait关键词,Trait不能实例化</p>
<p>如下代码实例:</p>
<div class="cnblogs_code">
<pre><?<span style="color: rgba(0, 0, 0, 1)">php
trait Dog{
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(128, 0, 128, 1)">$name</span>="dog"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> bark(){
</span><span style="color: rgba(0, 0, 255, 1)">echo</span> "This is dog"<span style="color: rgba(0, 0, 0, 1)">;
}
}
</span><span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> Animal{
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> eat(){
</span><span style="color: rgba(0, 0, 255, 1)">echo</span> "This is animal eat"<span style="color: rgba(0, 0, 0, 1)">;
}
}
</span><span style="color: rgba(0, 0, 255, 1)">class</span> Cat <span style="color: rgba(0, 0, 255, 1)">extends</span><span style="color: rgba(0, 0, 0, 1)"> Animal{
</span><span style="color: rgba(0, 0, 255, 1)">use</span><span style="color: rgba(0, 0, 0, 1)"> Dog;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> drive(){
</span><span style="color: rgba(0, 0, 255, 1)">echo</span> "This is cat drive"<span style="color: rgba(0, 0, 0, 1)">;
}
}
</span><span style="color: rgba(128, 0, 128, 1)">$cat</span> = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Cat();
</span><span style="color: rgba(128, 0, 128, 1)">$cat</span>-><span style="color: rgba(0, 0, 0, 1)">drive();
</span><span style="color: rgba(0, 0, 255, 1)">echo</span> "<br/>"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(128, 0, 128, 1)">$cat</span>-><span style="color: rgba(0, 0, 0, 1)">eat();
</span><span style="color: rgba(0, 0, 255, 1)">echo</span> "<br/>"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(128, 0, 128, 1)">$cat</span>-><span style="color: rgba(0, 0, 0, 1)">bark();
</span>?></pre>
</div>
<p> </p>
<p>将会如下输出</p>
<p class="ztext-empty-paragraph"> </p>
<img class="origin_image zh-lightbox-thumb lazy" src="https://pic2.zhimg.com/80/v2-d90d5ed3bb0935c81126ed1719c5c81d_hd.jpg" alt="" width="474" data-caption="" data-size="normal" data-rawwidth="474" data-rawheight="234" data-original="https://pic2.zhimg.com/v2-d90d5ed3bb0935c81126ed1719c5c81d_r.jpg" data-actualsrc="https://pic2.zhimg.com/v2-d90d5ed3bb0935c81126ed1719c5c81d_b.jpg" data-lazy-status="ok">
<h3>再测试Trait、基类和本类对同名属性或方法的处理,如下代码</h3>
<div class="cnblogs_code">
<pre><?<span style="color: rgba(0, 0, 0, 1)">php
trait Dog{
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(128, 0, 128, 1)">$name</span>="dog"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> drive(){
</span><span style="color: rgba(0, 0, 255, 1)">echo</span> "This is dog drive"<span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> eat(){
</span><span style="color: rgba(0, 0, 255, 1)">echo</span> "This is dog eat"<span style="color: rgba(0, 0, 0, 1)">;
}
}
</span><span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> Animal{
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> drive(){
</span><span style="color: rgba(0, 0, 255, 1)">echo</span> "This is animal drive"<span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> eat(){
</span><span style="color: rgba(0, 0, 255, 1)">echo</span> "This is animal eat"<span style="color: rgba(0, 0, 0, 1)">;
}
}
</span><span style="color: rgba(0, 0, 255, 1)">class</span> Cat <span style="color: rgba(0, 0, 255, 1)">extends</span><span style="color: rgba(0, 0, 0, 1)"> Animal{
</span><span style="color: rgba(0, 0, 255, 1)">use</span><span style="color: rgba(0, 0, 0, 1)"> Dog;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> drive(){
</span><span style="color: rgba(0, 0, 255, 1)">echo</span> "This is cat drive"<span style="color: rgba(0, 0, 0, 1)">;
}
}
</span><span style="color: rgba(128, 0, 128, 1)">$cat</span> = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Cat();
</span><span style="color: rgba(128, 0, 128, 1)">$cat</span>-><span style="color: rgba(0, 0, 0, 1)">drive();
</span><span style="color: rgba(0, 0, 255, 1)">echo</span> "<br/>"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(128, 0, 128, 1)">$cat</span>-><span style="color: rgba(0, 0, 0, 1)">eat();
</span>?></pre>
</div>
<p> </p>
<img class="origin_image zh-lightbox-thumb lazy" src="https://pic1.zhimg.com/80/v2-f27fa4adbd84fe4a5840598784b5e388_hd.jpg" alt="" width="459" data-caption="" data-size="normal" data-rawwidth="459" data-rawheight="194" data-original="https://pic1.zhimg.com/v2-f27fa4adbd84fe4a5840598784b5e388_r.jpg" data-actualsrc="https://pic1.zhimg.com/v2-f27fa4adbd84fe4a5840598784b5e388_b.jpg" data-lazy-status="ok">
<p>所以:Trait中的方法或属性会覆盖 基类中的同名的方法或属性,而本类会覆盖Trait中同名的属性或方法</p>
<h3>一个类可以组合多个Trait,通过逗号相隔,如下</h3>
<p>use trait1,trait2</p>
<p>当不同的trait中,却有着同名的方法或属性,会产生冲突,可以使用insteadof或 as进行解决,insteadof 是进行替代,而as是给它取别名<br>如下实例:</p>
<div class="cnblogs_code">
<pre><?<span style="color: rgba(0, 0, 0, 1)">php
trait trait1{
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> eat(){
</span><span style="color: rgba(0, 0, 255, 1)">echo</span> "This is trait1 eat"<span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> drive(){
</span><span style="color: rgba(0, 0, 255, 1)">echo</span> "This is trait1 drive"<span style="color: rgba(0, 0, 0, 1)">;
}
}
trait trait2{
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> eat(){
</span><span style="color: rgba(0, 0, 255, 1)">echo</span> "This is trait2 eat"<span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> drive(){
</span><span style="color: rgba(0, 0, 255, 1)">echo</span> "This is trait2 drive"<span style="color: rgba(0, 0, 0, 1)">;
}
}
</span><span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> cat{
</span><span style="color: rgba(0, 0, 255, 1)">use</span> trait1,<span style="color: rgba(0, 0, 0, 1)">trait2{
trait1</span>::<span style="color: rgba(0, 0, 0, 1)">eat insteadof trait2;
trait1</span>::<span style="color: rgba(0, 0, 0, 1)">drive insteadof trait2;
}
}
</span><span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> dog{
</span><span style="color: rgba(0, 0, 255, 1)">use</span> trait1,<span style="color: rgba(0, 0, 0, 1)">trait2{
trait1</span>::<span style="color: rgba(0, 0, 0, 1)">eat insteadof trait2;
trait1</span>::<span style="color: rgba(0, 0, 0, 1)">drive insteadof trait2;
trait2</span>::eat <span style="color: rgba(0, 0, 255, 1)">as</span><span style="color: rgba(0, 0, 0, 1)"> eaten;
trait2</span>::drive <span style="color: rgba(0, 0, 255, 1)">as</span><span style="color: rgba(0, 0, 0, 1)"> driven;
}
}
</span><span style="color: rgba(128, 0, 128, 1)">$cat</span> = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> cat();
</span><span style="color: rgba(128, 0, 128, 1)">$cat</span>-><span style="color: rgba(0, 0, 0, 1)">eat();
</span><span style="color: rgba(0, 0, 255, 1)">echo</span> "<br/>"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(128, 0, 128, 1)">$cat</span>-><span style="color: rgba(0, 0, 0, 1)">drive();
</span><span style="color: rgba(0, 0, 255, 1)">echo</span> "<br/>"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">echo</span> "<br/>"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">echo</span> "<br/>"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(128, 0, 128, 1)">$dog</span> = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> dog();
</span><span style="color: rgba(128, 0, 128, 1)">$dog</span>-><span style="color: rgba(0, 0, 0, 1)">eat();
</span><span style="color: rgba(0, 0, 255, 1)">echo</span> "<br/>"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(128, 0, 128, 1)">$dog</span>-><span style="color: rgba(0, 0, 0, 1)">drive();
</span><span style="color: rgba(0, 0, 255, 1)">echo</span> "<br/>"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(128, 0, 128, 1)">$dog</span>-><span style="color: rgba(0, 0, 0, 1)">eaten();
</span><span style="color: rgba(0, 0, 255, 1)">echo</span> "<br/>"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(128, 0, 128, 1)">$dog</span>-><span style="color: rgba(0, 0, 0, 1)">driven();
</span>?></pre>
</div>
<p> </p>
<p>输出如下</p>
<p class="ztext-empty-paragraph"> </p>
<img class="origin_image zh-lightbox-thumb lazy" src="https://pic4.zhimg.com/80/v2-c710d1d33824e2cdaffe726d21e84233_hd.jpg" alt="" width="555" data-caption="" data-size="normal" data-rawwidth="555" data-rawheight="318" data-original="https://pic4.zhimg.com/v2-c710d1d33824e2cdaffe726d21e84233_r.jpg" data-actualsrc="https://pic4.zhimg.com/v2-c710d1d33824e2cdaffe726d21e84233_b.jpg" data-lazy-status="ok">
<h3>as 还可以修改方法的访问控制</h3>
<div class="cnblogs_code">
<pre><?<span style="color: rgba(0, 0, 0, 1)">php
trait Animal{
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> eat(){
</span><span style="color: rgba(0, 0, 255, 1)">echo</span> "This is Animal eat"<span style="color: rgba(0, 0, 0, 1)">;
}
}
</span><span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> Dog{
</span><span style="color: rgba(0, 0, 255, 1)">use</span><span style="color: rgba(0, 0, 0, 1)"> Animal{
eat </span><span style="color: rgba(0, 0, 255, 1)">as</span> <span style="color: rgba(0, 0, 255, 1)">protected</span><span style="color: rgba(0, 0, 0, 1)">;
}
}
</span><span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> Cat{
</span><span style="color: rgba(0, 0, 255, 1)">use</span><span style="color: rgba(0, 0, 0, 1)"> Animal{
Animal</span>::eat <span style="color: rgba(0, 0, 255, 1)">as</span> <span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> eaten;
}
}
</span><span style="color: rgba(128, 0, 128, 1)">$dog</span> = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Dog();
</span><span style="color: rgba(128, 0, 128, 1)">$dog</span>->eat();<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">报错,因为已经把eat改成了保护</span>
<span style="color: rgba(128, 0, 128, 1)">$cat</span> = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Cat();
</span><span style="color: rgba(128, 0, 128, 1)">$cat</span>->eat();<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">正常运行,不会修改原先的访问控制</span>
<span style="color: rgba(128, 0, 128, 1)">$cat</span>->eaten();<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">报错,已经改成了私有的访问控制</span>
?></pre>
</div>
<p> </p>
<h3>Trait也可以互相组合,还可以使用抽象方法,静态属性,静态方法等,实例如下</h3>
<div class="cnblogs_code">
<pre><?<span style="color: rgba(0, 0, 0, 1)">php
trait Cat{
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> eat(){
</span><span style="color: rgba(0, 0, 255, 1)">echo</span> "This is Cat eat"<span style="color: rgba(0, 0, 0, 1)">;
}
}
trait Dog{
</span><span style="color: rgba(0, 0, 255, 1)">use</span><span style="color: rgba(0, 0, 0, 1)"> Cat;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> drive(){
</span><span style="color: rgba(0, 0, 255, 1)">echo</span> "This is Dog drive"<span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 0, 255, 1)">abstract</span> <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> getName();
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> test(){
</span><span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(128, 0, 128, 1)">$num</span>=0<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(128, 0, 128, 1)">$num</span>++<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">echo</span> <span style="color: rgba(128, 0, 128, 1)">$num</span><span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> say(){
</span><span style="color: rgba(0, 0, 255, 1)">echo</span> "This is Dog say"<span style="color: rgba(0, 0, 0, 1)">;
}
}
</span><span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> animal{
</span><span style="color: rgba(0, 0, 255, 1)">use</span><span style="color: rgba(0, 0, 0, 1)"> Dog;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> getName(){
</span><span style="color: rgba(0, 0, 255, 1)">echo</span> "This is animal name"<span style="color: rgba(0, 0, 0, 1)">;
}
}
</span><span style="color: rgba(128, 0, 128, 1)">$animal</span> = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> animal();
</span><span style="color: rgba(128, 0, 128, 1)">$animal</span>-><span style="color: rgba(0, 0, 0, 1)">getName();
</span><span style="color: rgba(0, 0, 255, 1)">echo</span> "<br/>"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(128, 0, 128, 1)">$animal</span>-><span style="color: rgba(0, 0, 0, 1)">eat();
</span><span style="color: rgba(0, 0, 255, 1)">echo</span> "<br/>"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(128, 0, 128, 1)">$animal</span>-><span style="color: rgba(0, 0, 0, 1)">drive();
</span><span style="color: rgba(0, 0, 255, 1)">echo</span> "<br/>"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(128, 0, 128, 1)">$animal</span>::<span style="color: rgba(0, 0, 0, 1)">say();
</span><span style="color: rgba(0, 0, 255, 1)">echo</span> "<br/>"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(128, 0, 128, 1)">$animal</span>-><span style="color: rgba(0, 0, 0, 1)">test();
</span><span style="color: rgba(0, 0, 255, 1)">echo</span> "<br/>"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(128, 0, 128, 1)">$animal</span>-><span style="color: rgba(0, 0, 0, 1)">test();
</span>?></pre>
</div>
<p> </p>
<p>输出如下</p>
<p class="ztext-empty-paragraph"> </p>
<img class="origin_image zh-lightbox-thumb lazy" src="https://pic1.zhimg.com/80/v2-d93f6e8f6d4a0ba908d5c2c2734c76ac_hd.jpg" alt="" width="549" data-caption="" data-size="normal" data-rawwidth="549" data-rawheight="254" data-original="https://pic1.zhimg.com/v2-d93f6e8f6d4a0ba908d5c2c2734c76ac_r.jpg" data-actualsrc="https://pic1.zhimg.com/v2-d93f6e8f6d4a0ba908d5c2c2734c76ac_b.jpg" data-lazy-status="ok"></div>
<div class="RichText ztext Post-RichText"> </div>
<div class="RichText ztext Post-RichText"><span style="color: rgba(255, 0, 0, 1); font-size: 14pt">最常见的应用场景就是将底层的curd用trait封装,然后在控制器中调用即可</span></div>
<div class="RichText ztext Post-RichText"> </div>
<div class="RichText ztext Post-RichText"><span style="color: rgba(192, 192, 192, 1)">参考文章:<span style="color: rgba(192, 192, 192, 1)">https://zhuanlan.zhihu.com/p/81123521</span></span> </div>
</div>
</div>
<div id="MySignature" role="contentinfo">
let the world have no hard-to-write code^-^<br><br>
来源:https://www.cnblogs.com/ovim/p/11524193.html
頁:
[1]