2013-07-15 3 views
1

Короче у меня естьПочему это заявление несовместимо?

abstract class AbstractMapper implements MapperInterface { 

    public function fetch(EntityInterface $entity, Array $conditions = array()) { 
     . . . 
    } 

} 

interface MapperInterface { 

    public function fetch(EntityInterface $entity, Array $conditions = array()); 

} 

abstract class AbstractUserMapper extends AbstractMapper implements UserMapperInterface { 

    public function fetch(UserInterface $user, Array $conditions = array()) { 

     $conditions = array_merge($conditions, array('type' => $user->getType())); 

     return parent::fetch($user, $conditions); 
    } 

} 

interface UserMapperInterface { 

    public function fetch(UserInterface $user, Array $conditions = array()); 

} 

Это ошибка, я получаю:

Фатальная ошибка: Декларация Типовыми \ Data \ Картостроители \ AbstractUserMapper :: выборки() должна быть совместима с Model \ Data \ Mappers \ Interfaces \ MapperInterface :: выборки()

Если я изменю UserInterface к EntityInterface это работает, но это только кажется неправильным, а также в моем AbstractUserMapper::fetch(), когда я печатаю $user мой IDE показывает только методы, объявленные в моей EntityInterface и getType() нет в этом списке.

Я знаю, что я все еще могу разместить $user->getType(), потому что я знаю объект, который у меня есть, UserInterface, но все это кажется неправильным, даже моя IDE думает так, или я чего-то не хватает?

Почему это не работает? Это испортит мой код, если мне нужно поставить EntityInterface вместо «UserInterface, я думаю.

+0

Это может быть потому, что ваш AbstractUserMapper расширяет AbstractMapper но ваши выборки() не совпадают. Возможно, попробуйте добавить метод fetchUser() вместо того же имени функции. –

+6

Интерфейс - это контракт о том, что вы поддерживаете, вы не можете сказать _ «первый аргумент - это« EntityInterface », а первым аргументом является« UserInterface ».» _ , Вы либо ожидаете, либо потребуете, чтобы первый аргумент имел возможности «EntityInterface» или «UserInterface». Дело в том, что если вы _need_' UserInterface' в 'AbstractUserMapper :: fetch()', то он просто _ не реализует 'MapperInterface :: fetch()' _, так как он должен был бы иметь дело с с _any_ 'EntityInterface', а не только с' UserInterface' ... – Wrikken

+0

Разве вы не подумали бы, что если UserInterface расширяет EntityInterface, это позволит мне делать то, что я хочу сделать, потому что он будет знать, что UserInterface также обладает возможностями от EntityInterface и не должно быть никаких проблем, насколько я вижу. Это всего лишь вещь PHP? – ibanore

ответ

3

Проблема заключается здесь:

abstract class AbstractUserMapper 
    extends AbstractMapper 
    implements UserMapperInterface 

В качестве первого шага, проверьте определение AbstractMapper:

abstract class AbstractMapper 
    implements MapperInterface 

определения интерфейсов между родительским и дочерними классами являются переходными, так что мы можем объединить первый определение:

abstract class AbstractUserMapper 
    extends AbstractMapper 
    implements UserMapperInterface, MapperInterface 

Это означает, что ваш класс должен быть реализован:

public function fetch(EntityInterface $entity, Array $conditions = array()); 

public function fetch(UserInterface $user, Array $conditions = array()); 

А это невозможно, потому что перегрузка метода не существует в PHP.

Возможное решение

Если предположить, что следующие определения интерфейса:

interface EntityInterface {} 
interface UserInterface extends EntityInterface {} 

Я хотел бы предложить, чтобы опускать implements UserMapperInterface:

abstract class AbstractUserMapper extends AbstractMapper 
Смежные вопросы