php trait 用法注意事项
减肥是一件大事,先让我吃饱了,再来好好计划计划。
Trait 和类相似,支持定义方法和属性,但他却不是类,不支持定义构造函数,因而不能实例化,只能被其他类使用,要在一个类中使用 Trait,可以通过 use 关键字引入,然后就可以在类方法中直接使用 trait 中定义的方法了。
trait Power {
protected function gas()
{
return '汽油';
}
protected function battery()
{
return '电池';
}
}
使用
class Car {
use Power;
public function drive()
{
echo "动力来源:" . $this->gas() . PHP_EOL;
echo "汽车启动..." . PHP_EOL;
}
}
我们可以轻松通过 Trait + 类的组合扩展类的功能,在某个类中使用了 Trait 之后,就好像把它的所有代码合并到这个类中一样,可以自由调用,并且同一个 Trait 可以被多个类复用,从而突破 PHP 单继承机制的限制,有效提升代码复用性和扩展性。
注意,trait 有对应的可见性,方法是private属性也可以被直接访问
trait Power {
protected function gas()
{
return '汽油';
}
public function battery()
{
return '电池';
}
private function water()
{
return '水';
}
}
class Car {
use Power;
public function drive()
{
echo "动力来源:" . $this->water() . PHP_EOL;
echo "切换动力来源:" . $this->battery() . PHP_EOL;
echo "切换动力来源:" . $this->gas() . PHP_EOL;
}
}
$car = new Car();
$car->drive();
在来举个特例,在trait 中添加一个属性
trait Power {
// 属性
protected $power;
protected function gas()
{
$this->power = '汽油';
}
public function battery()
{
$this->power = '电池';
}
private function water()
{
$this->power = '水';
}
}
class Car
{
use Power;
public function drive()
{
// 设置动力来源
$this->gas();
echo "动力来源:" . $this->power . PHP_EOL;
}
}
$car = new Car();
$car->drive();
可以看到,我们在 Trait 中可以使用 $this 指向当前 Trait 定义的属性和方法,因为 Trait 最终会被类使用,$this 也就最终对应着被使用类的对象实例。然后我们在使用类 Car 中可以通过 $this->power 调用 Trait 属性,就好像调用自己的属性一样。
注意:如此在使用的trait 类中也定义了相同的属性的名的话,会出现冲突
class Car
{
protected $power; // 再次定义会出现问题
use Power;
public function drive()
{
// 设置动力来源
$this->gas();
echo "动力来源:" . $this->power . PHP_EOL;
}
}
在另一篇文章中已经解释了 如何使用trait的类 和 trait 里面的方法重名使用的优先级问题
(查看优先级请点击)
trait Power
{
protected $power;
protected function gas()
{
$this->power = '汽油';
}
protected function battery()
{
$this->power = '电池';
}
// 同名方法
public function print()
{
echo "动力来源:" . $this->power . PHP_EOL;
}
}
trait Engine
{
protected $engine;
protected function three()
{
$this->engine = 3;
}
protected function four()
{
$this->engine = 4;
}
// 同名方法
public function print()
{
echo "发动机个数:" . $this->engine . PHP_EOL;
}
}
class Car
{
// 这里就出出现问题 - 因为两个trait里面有同名的方法
use Power, Engine;
public function drive()
{
}
}
不过不用担心新,php 也提供了相对应的解决方法
class Car
{
use Power, Engine {
Engine::printText insteadof Power;
}
public function drive()
{
// 设置动力来源
$this->gas();
$this->four();
$this->printText();
echo "汽车启动..." . PHP_EOL;
}
}
如果还是想调佣内部的方法,则需要如下操作
class Car
{
use Power, Engine {
Engine::printText insteadof Power;
Power::printText as printPower;
Engine::printText as printEngine;
}
public function drive()
{
// 设置动力来源
$this->gas();
$this->four();
$this->printPower();
$this->printText();
$this->printEngine();
echo "汽车启动..." . PHP_EOL;
}
}
以上就是trait 使用的一些注意事项