Класс, реализующий интерфейс, должен быть объявлен перед дочерним классом? - PullRequest
6 голосов
/ 19 декабря 2011

Я наткнулся на интересную проблему сегодня. В контексте одного файла для нескольких объявлений, если класс B реализует интерфейс A, а класс C расширяет класс A, класс B должен быть объявлен до класс C.

Следующий код не работает:

interface A {}
class C extends B {} // Class 'B' not found
class B implements A {}

Это исправляет:

interface A {}
class B implements A {}
class C extends B {} // Class 'B' is found

Но это прекрасно работает:

class A {}
class C extends B {} // Class 'B' is found
class B extends A {}

Это мои результаты на PHP 5.3.8 (Win32) и PHP 5.3.3-1ubuntu9.6 с suhosin.

Итак, вопрос в том, является ли это документированным поведением? Почему оно будет работать с классами, а не с интерфейсами? Или это следует считать ошибкой?

Дайте мне знать о вашем опыте, прежде чем я начну копаться в исходном коде PHP и / или открою билет с ошибкой PHP. :)

Спасибо!

Примечание: я знаю, что это просто вопрос порядка объявления классов, но это озадачивает меня ... Если это неуместно, пожалуйста, не стесняйтесь закрывать.

1 Ответ

8 голосов
/ 19 декабря 2011

Да, это задокументированное поведение:

Наследование объектов (примечание) :

Если не используется автозагрузка, классы должны быть определены до их использования. Если класс расширяет другой, тогда родительский класс должен быть объявлен перед структурой дочернего класса. Это правило применяется к классу, который наследует другие классы и интерфейсы.

1015 *

PHP: расширяет - Руководство (Примечание)

Классы должны быть определены до их использования! Если вы хотите, чтобы класс Named_Cart расширял класс Cart, вам нужно сначала определить класс Cart. Если вы хотите создать другой класс с именем Yellow_named_cart, основанный на классе Named_Cart, вы должны сначала определить Named_Cart. Короче говоря: важен порядок, в котором определяются классы.


Неопределенное поведение (с добавленным сарказмом)

Несмотря на то, что ваш третий пример мог бы сказать, что он не работает в соответствии с документацией (и я не могу найти какую-либо запись в журнале изменений, указывающую, что это введенная функция).

К сожалению, документация по PHP не на 100%, но вы можете доверять только тому, что знаете, и приведенные выше цитаты - это все, что я могу найти по этому вопросу.

Вы могли бы назвать это ошибкой, но в C ++ мы бы описали это как undefined behavior т.е. то, на что нельзя полагаться.


Если «стандарт» (документация) не упоминает об этом, его использование небезопасно.

Если «стандарт» (документация) не упоминает об этом, это может привести к взрыву вселенной или к хищнику, прыгнувшему через ваше окно. Не делай ничего, что может убить нас всех!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...