2015-02-11 3 views
1

Интересно, работает ли мой PHP-интерпретатор неправильно или если я неправильно понимаю черты. Вот мой фрагмент кода:Зачем черта не отменяет метод в классе?

<?php 

trait ExampleTrait{ 
    public function foo() 
    { 
     echo 'y'; 
    } 
} 

class ExampleClass 
{ 
    use ExampleTrait; 

    public function foo() 
    { 
     echo 'x'; 
    } 
} 

$exCl = new ExampleClass(); 

$exCl->foo(); 

Я предполагаю, что это должно показать «y», но вместо этого оно отображает «x». Зачем?

+3

Из руководства по php: Унаследованный элемент из базового класса переопределяется элементом, вставленным в Trait. Порядок приоритета состоит в том, что члены из текущего класса переопределяют методы Trait, которые, в свою очередь, переопределяют унаследованные методы. –

+0

@ Debflav хорошо нет, но не как расширенные классы, так как при расширении класса дочерний класс перезаписывает методы из родительского класса (если есть). Хотя при вставке признака внутри класса метод из класса имеет приоритет над признаком. –

+0

@AndreiP., Спасибо, я думаю, я просто не нашел этого в руководстве – drakonli

ответ

3

Прочтите это внимательно Trait documentation Я рекомендую попробовать каждый пример и внести свои изменения, чтобы убедиться, что вы его понимаете. Существует мой пример, надеюсь, что это помогает:

<?php 
class A { 
    public function foo() { 
     echo "x"; 
    } 
} 

class B extends A {} 

$test = new B(); 
$test->foo(); 

// result X 

Это довольно ясно, что я думаю, так что теперь позволяет использовать Черту:

<?php 
class A { 
    public function foo() { 
     echo "x"; 
    } 
} 

trait T { 
    public function foo() { 
     echo "y"; 
    } 
} 

class B extends A { 
    use T; 
} 

$test = new B(); 
$test->foo(); 

// result y 

Как вы можете видеть, метод Черты переписывает метод базового класса. А теперь позволяет создать метод Foo в классе B

<?php 
class A { 
    public function foo() { 
     echo "x"; 
    } 
} 

trait T { 
    public function foo() { 
     echo "y"; 
    } 
} 

class B extends A { 
    use T; 
    public function foo() { 
     echo "z"; 
    } 
} 

$test = new B(); 
$test->foo(); 

// result z 

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

+0

Да, но что, если у Trait есть метод 'bar', используемый в методе' foo', а класс A использует trat T и он переопределяет метод признака 'bar' с его собственной реализацией. Все хорошо, но тогда B расширяет A и имеет собственную реализацию 'bar', тогда вызов' B-> foo() 'будет использовать перезаписанный метод' bar() 'класса' A' вместо того, который находится на 'B '. Это отстой :-( –

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