与其他特质方法的碰撞

lau*_*kok 34 php traits php-5.5

如何使用同名方法处理特征?

trait FooTrait {
  public function fooMethod() {
        return 'foo method';
  }

  public function getRow() {
        return 'foo row';
  }
}

trait TooTrait {
    public function tooMethod() {
        return 'too method';
    }

    public function getRow() {
        return 'too row';
    }
}

class Boo
{
    use FooTrait;
    use TooTrait;

    public function booMethod() {
        return $this->fooMethod();
    }
}
Run Code Online (Sandbox Code Playgroud)

错误,

致命错误:特征方法getRow尚未应用,因为在Boo中存在与其他特征方法的冲突...

我该怎么办呢?

而且,使用两个相同的方法名称,我如何从中获取方法trait FooTrait

$a = new Boo;
var_dump($a->getRow()); // Fatal error: Call to undefined method Boo::getRow() in... 
Run Code Online (Sandbox Code Playgroud)

编辑:

class Boo
{
    use FooTrait, TooTrait {
        FooTrait::getRow insteadof TooTrait;
    }

    public function booMethod() {
        return $this->fooMethod();
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我想getRowTooTraitvia 获取方法Boo怎么办?可能吗?

Mar*_*rno 64

PHP有关冲突的文档:

如果两个Traits插入具有相同名称的方法,则在未明确解决冲突时会产生致命错误.

要解决同一类中使用的Traits之间的命名冲突,需要使用insteadof运算符来精确选择其中一个冲突方法.

由于这只允许排除方法,因此可以使用as运算符允许在另一个名称下包含一个冲突方法.

示例#5冲突解决

在这个例子中,Talker使用特征A和B.由于A和B具有冲突的方法,它定义使用来自特征B的smallTalk变体,以及来自特征A的bigTalk变体.

Aliased_Talker使用as运算符,可以在另外的别名对话中使用B的bigTalk实现.

<?php
trait A {
    public function smallTalk() {
        echo 'a';
    }

    public function bigTalk() {
        echo 'A';
    }
}

trait B {
    public function smallTalk() {
        echo 'b';
    }

    public function bigTalk() {
        echo 'B';
    }
}

class Talker {
    use A, B {
        B::smallTalk insteadof A;
        A::bigTalk insteadof B;
    }
}

class Aliased_Talker {
    use A, B {
        B::smallTalk insteadof A;
        A::bigTalk insteadof B;
        B::bigTalk as talk;
    }
}
Run Code Online (Sandbox Code Playgroud)

所以在你的情况下它可能是

class Boo {
    use FooTrait, TooTrait {
        FooTrait::getRow insteadof TooTrait;
    }

    public function booMethod() {
        return $this->fooMethod();
    }
}
Run Code Online (Sandbox Code Playgroud)

(即使你分开也行use,但我认为它更清楚)

或者使用as声明别名.

  • 声明一个别名.`TooTrait :: getRow as getRowOfToo;`试试 (3认同)