2015-08-03 132 views
2

我陷入了一个我无法自己解决的问题。如何覆盖抽象类中的特征方法?

我有延伸的抽象类(对我来说这些都是几个控制器类和抽象类Controller,所使用的框架不会是这里很重要,因为这是一个普遍的问题,PHP ...)类使用特质。我想重写一个方法定义在其中的一个特点。这只有在我的子类中定义方法但不在抽象类中时才有效。


所以,这一个完美的作品:

class MyController extends Controller 
{ 
    use AnyTrait; 

    public function anyMethodFromAnyTrait() 
    { 
     // override AnyTrait::anyMethodFromAnyTrait() 
    } 
} 

我也知道如何从AnyTrait使用as调用anyMethodFromAnyTrait方法。

class MyController extends Controller 
{ 
    use AnyTrait { AnyTrait::anyMethodFromAnyTrait as method } 

    public function anyMethodFromAnyTrait() 
    { 
     // invoke AnyTrait::anyMethodFromAnyTrait() 
     $this->method(); 
    } 
} 

两者都像魅力一样工作。


但我的问题有点不同。

当使用特点,在我抽象类定义方法我不能够覆盖性状的方法。

假设下列的控制器类:

class MyController extends Controller 
{ 
    public function anyAction() 
    { 
     // let's see what happens… 
     $this->anyMethodFromAnyTrait(); 
    } 
} 

...和抽象的多数民众赞成由MyController扩展:

abstract class Controller 
{ 
    use AnyTrait 

    public function anyMethodFromAnyTrait() 
    { 
     // do something different than AnyTrait 
    } 
} 

...这是何等的不工作。每当我呼叫$this->anyMethodFromAnyTrait()MyController内,将调用在AnyTrait中实施的特征的方法。我的摘要Controller中的同名方法将被忽略。

因此,我只能在具体子类中重写trait的方法,但不能在由该子类扩展的抽象类中重写。

因此,性状中的方法定义比抽象类中的相同方法定义获得PHP更高的优先级。

您是否知道该行为的任何解决方法?

+0

我不能重现与PHP 5.5或PHP 7的行为?请你把我链接到一个具体的http://3v4l.org重现案例? – bwoebi

+0

任何你不能在Controller中使用'使用AnyTrait {AnyTrait :: anyMethodFromAnyTrait作为方法}的原因? – Marek

+0

您是否找到任何解决方案? – llioor

回答

1

一种解决方法是仅在子类中使用特征。 PHP总是偏好“本地”特征方法。

它在子类中工作的原因是超类的特征方法被扩展,而不是特征使用本身。

+0

感谢您的回复。这种解决方法实际上是我想要避免的,因为我可以想象出于某种原因使用抽象类。 ;-) – Arvid

+0

但是为什么使用一个特质的函数,然后在同一个类中覆盖它? 你想实现什么?或者它的功能“不需要”的特质? – devnull

+0

该功能绝对是想要的,这就是为什么我使用这个特质。但是我想通过在开头添加几行代码来改变方法的行为。不幸的是,这个特质是我正在使用的框架的一部分,因此我不能只是改变方法本身。 ...我想我会实现一个完整的其他解决方案,我不需要重写特征函数。 – Arvid