2016-08-03 5 views
1

У меня есть следующие интерфейсные/классы:PHP подпись Override интерфейса в дочернем классе

class Part {} 
class Engine extends Part{} 

interface CarsInterface { 
    public function selectTimeLine(Part $object); 
} 

abstract class Car implements CarsInterface {} 

class Hybrid extends Car { 
    public function selectTimeLine(Engine $object) {} 
} 

Почему я не могу использовать объект Engine в детской подписи (Hybrid Class), если двигатель является подклассом «Часть «(Я знаю, что это возможно в Java ...)

Каков правильный способ достижения этой функциональности в PHP? Thx

+0

Там есть несколько вопросов, которые касаются этого. Это кажется наиболее перспективным, предлагает использовать instanceof: http://programmers.stackexchange.com/questions/227766/changing-method-signature-for-implementing-classes-in-php Вот один из SO: http: // stackoverflow .com/questions/13423494/why-is-overriding-method-parameters-a-нарушение-strict-standards-in-php. Лучше всего, вероятно, удалить тип из объявления аргумента и использовать 'instanceof'. –

+0

@MontgomeryJean Я увидел второй ответ, озираясь по сторонам ... но можете ли вы подробнее остановиться на «instanceof», можете ли вы привести пример? –

+0

никогда не видел ... видел. –

ответ

3

Да, PHP отстой. =)

Если я не ошибаюсь, вам нужно что-то вроде:

interface SomeInterface { 
} 

class Part implements SomeInterface {} 
class Engine extends Part implements SomeInterface{} 

interface CarsInterface { 
    public function selectTimeLine(SomeInterface $object); 
} 

abstract class Car implements CarsInterface {} 

class Hybrid extends Car { 
    public function selectTimeLine(SomeInterface $object) {} 
} 
+0

Поскольку 'Part' реализует' SomeInterface' и 'Engine' extends' Part', объект 'Engine' также будет реализовывать' SomeInterface', см. Мой пример и для тестового примера http://ideone.com/6CNdhk. – fyrye

1

Вкратце, интерфейс предназначен для предоставления вам этих ограничений путем установки конкретных инструкций для ваших объектов. Таким образом, при проверке возможностей объекта или с помощью instanceof вы всегда можете рассчитывать на получение того, что было указано.

Не существует «правильного» способа достижения желаемого результата, но предлагаемый метод заключается в том, чтобы набирать текст с помощью интерфейсов, а не конкретных определений классов.

Таким образом, вы всегда можете гарантировать доступные методы для предоставленных объектов.

interface TimeLineInterface { } 

class Part implements TimeLineInterface { } 

class Engine extends Part { } 

interface CarInterface 
{ 
    public function selectTimeLine(TimeLineInterface $object); 
} 

abstract class Car implements CarInterface { } 

class Hybrid extends Car 
{ 
    public function selectTimeLine(TimeLineInterface $object) { } 
} 

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

class Hybrid extends Car 
{ 
    public function selectTimeLine(TimeLineInterface $object) 
    { 
     if (!$object instanceof Engine) { 
      throw new \InvalidArgumentException(__CLASS__ . '::' . __FUNCTION__ . ' expects an instance of Engine. Received ' . get_class($object)); 
     } 
    } 
} 
Смежные вопросы