php trait 学习笔记

PHP中的类不支持多继承,但是提供了trait语法类解决单继承没法提供的多层代码复用问题。

要点:

Trait 不能通过它自身来实例化,但可以在类中使用,也可以通过静态调用使用trait中方法和属性。

<?php 

trait T{

public function t_method(){

echo "this is t_method<br>";

}

}

class C{

//在类中使用trait

use T;

public function c_method(){

echo "this is c_method<br>";

}

}

$cls= new  C();

$cls->t_method();

//通过类调用

$cls->c_method();

//静态调用

T::t_method();

?>


输出结果:

this is t_method
this is c_method
this is t_method


2   在类中使用trait,如果出现类的函数或属性于trait的函数或属性同名,就回会发生覆盖---》当前类中的方法会覆盖 trait 方法,而 trait 方法又覆盖了当前类父类中的方法。

<?php 
trait T{
public function sameWithBase(){
echo "this is trait's sameWithBase()<br>";
}

public function commonMethod(){
echo "this is trait's commonMethod()<br>";
}
}
class base{
public function sameWithBase(){
echo "this is base's sameWithBase()<br>";
}
public function commonMethod(){
echo "this is base's commonMethod()<br>";
}
}
class C extends base{
use T;
public function commonMethod(){
echo "this is class's commonMethod()<br>";
}
}

$cls=new C();

//trait方法覆盖父类方法

$cls->sameWithBase();

//当前类方法覆盖trait方法

$cls->commonMethod();

?>


输出结果

this is trait's sameWithBase()
this is class's commonMethod()

3   可以在同一个类中使用多个Trait,如果出现多个Trait中有函数或属性同名的情况,运行时就会报错。有两种方式解决,A方式:需要使用 insteadof 操作符来明确指定使用冲突方法中的哪一个 ,B方式:使用as 操作符可以将其中一个冲突的方法以另一个名称来引入

<?php 
trait T1{
public function sameName1(){
echo "this is T1's sameName1()<br>";
}

public function sameName2(){
echo "this is T1's sameName2()<br>";
}
}
trait T2{
public function sameName1(){
echo "this is T2's sameName1()<br>";
}

public function sameName2(){
echo "this is T2's sameName2()<br>";
}
}
class C{
use T1,T2{
//如果每个方法的作用都不同,那C使用T1,T2后,按理将会拥有4个方法。
//但是因为有同名方法,如果C只用sameName1()和sameName2()两个函数名,那C只能有拥有两个方法,
//而且调用sameName1()和sameName2()时程序并不知道是T1,还是T2中的,所以,重名的方法必须
//全部指定具体使用的是哪一个!
//需要使用 insteadof 操作符来明确指定使用冲突方法中的哪一个。 
T1::sameName1 insteadof T2;
T2::sameName2 insteadof T1;

//insteadof 必须有name1和name2,否则会报错
//as 为可选
//B方式在使用时给同名的方法或属性重命名
T2::sameName2 as rename;
T2::sameName1 as rename1;


}
}

$cls=new C();
$cls->sameName1();
$cls->sameName2();
$cls->rename();
$cls->rename1();
?>

输出结果

this is T1's sameName1()
this is T1's sameName2()
this is T2's sameName2()
this is T2's sameName1()


4   在使用时可以修改的访问属性。

<?php
trait HelloWorld {
    public function 
sayHello() {
        echo 
'Hello World!';
    }
}
// 修改 sayHello 的访问控制
class MyClass1 {
    use 
HelloWorld sayHello as protected; }
}
// 给方法一个改变了访问控制的别名
// 原版 sayHello 的访问控制则没有发生变化
class MyClass2 {
    use 
HelloWorld sayHello as private myPrivateHello; }
}
?>


5    可以用trait来组合trait。

<?php
trait Hello {
    public function 
sayHello() {
        echo 
'Hello ';
    }
}

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

trait 
HelloWorld {
    use 
HelloWorld;
}

class 
MyHelloWorld {
    use 
HelloWorld;
}

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

输出结果

Hello World!

6    trait中可以有属性,静态方法,抽象方法。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值