43

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

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();
    }
}

错误,

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

我该怎么办?

而且,有两个相同的方法名称,我怎样才能得到方法trait FooTrait

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

编辑:

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

    public function booMethod() {
        return $this->fooMethod();
    }
}

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

4

2 回答 2

88

关于冲突的 PHP 文档:

如果两个 Traits 插入同名的方法,如果冲突没有明确解决,则会产生致命错误。

要解决同一类中使用的 Traits 之间的命名冲突,需要使用而不是运算符来准确选择冲突方法之一。

由于这仅允许排除方法,因此 as 运算符可用于允许以另一个名称包含冲突方法之一。

Example #5 冲突解决

在这个例子中,Talker 使用了 trait A 和 B。由于 A 和 B 有冲突的方法,它定义使用来自 trait B 的 smallTalk 的变体,以及来自 trait 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;
    }
}

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

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

    public function booMethod() {
        return $this->fooMethod();
    }
}

即使你分开它也有效use,但我认为它更清楚

或者使用as来声明别名。

于 2014-07-31T16:48:18.103 回答
4

是的,你可以使用这样的东西(编辑内容的答案):

class Boo {
    use FooTrait, TooTrait {
        FooTrait::getRow as getFooRow;
        TooTrait::getRow as getTooRow;
    }

    public function getRow(... $arguments)
    {
         return [ 'foo' => $this->getFooRow(... $arguments), 'too' => $this->getTooRow(... $arguments) ];
    }

    public function booMethod(... $arguments)
    {
        return $this->getFooRow(... $arguments);
    }
}
于 2019-09-25T07:44:48.930 回答