2015-08-03 2 views
2

У меня возникла проблема с чертами, которые я не могу решить самостоятельно.Как переопределить метод признака в абстрактном классе?

У меня есть классы, простирающиесяабстрактный класс (в моем случае это несколько классов контроллеров и абстрактный класс Controller, используемая база не будет иметь важное значение здесь, так как это общий PHP вопрос ...) который использует черты. Я хотел бы, чтобы переопределил метод, определенный в одном из признаков. Это работает только до тех пор, пока я определяю метод в моих подклассах, но не в моем абстрактном классе.


Таким образом, это один работает отлично:

class MyController extends Controller 
{ 
    use AnyTrait; 

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

Я также знаю, как вызвать метод anyMethodFromAnyTrait из AnyTrait с помощью as.

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 будет проигнорирован.

Поэтому я могу переопределить метод признака в конкретном подклассе, но не в абстрактном классе, который расширен этим подклассом.

Таким образом, определения методов в чертах получают более высокий приоритет PHP, чем те же определения методов в абстрактных классах.

Знаете ли вы обходной путь для этого поведения?

+0

Я не могу воспроизвести это поведение ни с PHP 5.5, ни с PHP 7? Можете ли вы связать меня с конкретным случаем воспроизведения http://3v4l.org? – bwoebi

+0

По какой-либо причине вы не можете использовать 'использовать AnyTrait {AnyTrait :: anyMethodFromAnyTrait как метод}' в 'Controller'? – Marek

+0

Вы нашли решение? – llioor

ответ

1

Обходным способом было бы использовать признаки ТОЛЬКО в подклассах. PHP всегда предпочитает методы признаков над «локальными».

Причина, по которой он работает в подклассах, заключается в том, что метод признака суперкласса расширен, а не само использование признаков.

+0

Спасибо за ваш ответ. Такое обходное решение на самом деле является тем, чего я хочу избежать, поскольку я использую этот абстрактный класс по какой-то причине, как вы можете себе представить. ;-) – Arvid

+0

Но зачем использовать функцию признака, а затем перезаписать его в том же классе? Чего вы хотите достичь? Или это функция «нежелательна» в чертах? – devnull

+0

Функция определенно нужна, поэтому я использую эту черту. Но я хочу немного изменить поведение метода, добавив всего несколько строк кода к его началу. К сожалению, этот признак является частью структуры, которую я использую, и поэтому я не могу просто изменить сам метод. ... Я думаю, что я реализую полное другое решение, для которого мне не нужно переопределять функцию признака. – Arvid

Смежные вопросы