2016-03-28 1 views
7

У меня есть два PHP черты, которые каждый из наследуемых от того же 3-го признака:избежать столкновений признаков - use_once?

trait C { 
    public function smallTalk() { 
     echo 'c'; 
    } 
} 

trait A { 
    use C; 
    public function ac() { 
     echo 'a'.smallTalk(); 
    } 
} 

trait B { 
    use C; 
    public function bc() { 
     echo 'b'.smallTalk(); 
    } 
} 

И я хочу, чтобы использовать их как в классе:

class D { 
    use A, B; 
    public function acbc() { 
     echo ac().bc(); 
    } 
} 

, но я получаю ошибку

Fatal error: Trait method smallTalk has not been applied, because there are collisions with other trait methods on D

Я знаю use_once не вещь, но я ищу ту же функциональность, что require_once или include_once обеспечивает, но для черт. Этот пример упрощен. Мой реальный C имеет множество методов и наследуется многими более чем двумя чертами, поэтому я не хочу повторять длинную строку insteadof каждый раз, когда я использую более 1 из этих признаков.

+0

короткая версия: Нет, вручную обработки коллизий цена за использование черты. – VolkerK

+0

Я подозреваю, что вы злоупотребляете чертами. Я использую только черты как последнее средство. Этот ответ имеет хорошее объяснение альтернатив (на C++, но они в основном применяются к любому языку ООП) http://stackoverflow.com/questions/406081/why-should-i-avoid-multiple-inheritance-in-c# answer-407928 – Pevara

ответ

0

Вы должны прочитать: Conflict Resolution

If two Traits insert a method with the same name, a fatal error is produced, if the conflict is not explicitly resolved.

To resolve naming conflicts between Traits used in the same class, the insteadof operator needs to be used to choose exactly one of the conflicting methods.

Since this only allows one to exclude methods, the as operator can be used to allow the inclusion of one of the conflicting methods under another name.

Пример:

<?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; 
    } 
} 
+0

Вы прочитали вопрос? «У моего настоящего C есть множество методов и унаследовано многими более чем двумя чертами, поэтому я действительно не хочу повторять длинную строку вместо этого каждый раз, когда я использую более одного из этих признаков». Я знаю, что могу делать то, что вы говорите, но я спрашивал, есть ли решение _better_. – wogsland

+1

Вы не сможете разрешить конфликт другими способами. Используйте черту + расширенный. Если вы хотите сделать все «правильно» - не пытайтесь делать все с помощью признака. Вы можете создать класс C. D, расширенный от C. Без реального примера - трудно сказать, какая архитектура будет правдой. Я рекомендую познакомиться с SOLID. Он может помочь в выборе архитектуры. –

+0

Упрощенный, потому что это правильный ответ, даже если OP не нравится, что это правильный ответ. – mopsyd

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