您的位置:首页 > 编程语言 > PHP开发

PHP5.4 Trait 使用

2015-12-25 15:36 651 查看

Trait 是个什么鬼

PHP Trait 是一个抽象类, 不能实例化, 简单理解就是将trait的代码复制, 粘贴到你使用trait的类中. 和接口对比, 还是有区别的

有这么个问题.

<?php
class DbReader extends Mysqli
{
}

class FileReader extends SplFileObject
{
}

DbReader, FileReader 都需要些公共方法, 假设都设计为单列模式, 两个类都需要getInstance方法, php不支持多继承, 怎么办?

<?php
interface Singleton
{
public static function getInstance();
}

class DbReader extends Mysqli implements Singleton
{
public static function getInstance(){ return "instanceOfDbReader";}
}

class FileReader extends SplFileObject implements Singleton
{
public static function getInstance(){ return "instanceOfFileReader";}
}

是你想要的吗? 显然是NO

SO PHP特性 Trait

<?php
trait Singleton
{
private static $instance;

public static function getInstance() {
if (!(self::$instance instanceof self)) {
self::$instance = new self;
}
return self::$instance;
}
}

class DbReader extends ArrayObject
{
use Singleton;
}

class  FileReader
{
use Singleton;
}
$a = DbReader::getInstance();
$b = FileReader::getInstance();
var_dump($a);  //object(DbReader)
var_dump($b);  //object(FileReader)

是不是爽了!!!.

使用多个Trait

PHP Trait 是可以多个使用的

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

trait World
{
function sayWorld() {
echo "World";
}
}

class MyWorld
{
use Hello, World;
}

$world = new MyWorld();
echo $world->sayHello() . " " . $world->sayWorld(); //Hello World

是不是很方便!!!

Trait 组装 Trait

多个Trait可以组装成一个Trait

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

trait World
{
function sayWorld() {
echo "World";
}
}
trait HelloWorld
{
use Hello, World;
}

class MyWorld
{
use HelloWorld;
}

$world = new MyWorld();
echo $world->sayHello() . " " . $world->sayWorld(); //Hello World

Trait 优先级

Trait中的方法重写继承父类的方法.
当前类中方法复写trait中的方法

<?php
trait Hello
{
function sayHello() {
return "Hello";
}

function sayWorld() {
return "Trait World";
}

function sayHelloWorld() {
echo $this->sayHello() . " " . $this->sayWorld();
}

function sayBaseWorld() {
echo $this->sayHello() . " " . parent::sayWorld();
}
}

class Base
{
function sayWorld(){
return "Base World";
}
}

class HelloWorld extends Base
{
use Hello;
function sayWorld() {
return "World";
}
}

$h =  new HelloWorld();
$h->sayHelloWorld(); // Hello World
$h->sayBaseWorld(); // Hello Base World

解决Trait冲突

<?php
trait Game
{
function play() {
echo "Playing a game";
}
}

trait Music
{
function play() {
echo "Playing music";
}
}

class Player
{
use Game, Music;
}

$player = new Player();
$player->play(); // Fatal Error

// resolve one
class Player
{
use Game, Music {
Music::play insteadof Game;
}
}

$player = new Player();
$player->play(); //Playing music

// resolve two
class Player
{
use Game, Music {
Game::play as gamePlay;
Music::play insteadof Game;
}
}

$player = new Player();
$player->play(); //Playing music
$player->gamePlay(); //Playing a game

使用PHP Reflection类
ReflectionClass::getTraits()
获取类使用的traits.
ReflectionClass::getTraitNames()
获取类中trait名称
ReflectionClass::isTrait()
此类是否是trait

其他特性

trait中的
protected, private
可以随便访问

<?php
trait Message
{
private $message;

function alert() {
$this->define();
echo $this->message;
}
abstract function define();
}

class Messenger
{
use Message;
function define() {
$this->message = "Custom Message";
}
}

$messenger = new Messenger;
$messenger->alert(); //Custom Message

参考Shameer C's Blog
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: