Реализация интерфейса PHP отклоняет подклассы по параметрам - PullRequest
4 голосов
/ 24 января 2011

учтите это:

class A{}

class B extends A{}

interface I{
 // expects object instanceof A
 function doSomething(A $a);
}

class C implements I
{
 // fails ????
 function doSomething(B $b){}
}

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

Ответы [ 2 ]

6 голосов
/ 24 января 2011

class C implements I означает, что должно быть отношение подтипа между C и I.Это означает, что объект типа C должен использоваться везде, где требуется объект типа I.

В вашем случае C является более строгим, чем I, поскольку он предъявляет более точные требования к аргументу doSomething - I.doSomething подходит для любого A, но C.doSomething требует определенногоподтип A

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

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

2 голосов
/ 02 ноября 2013

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

немного поработать- instanceof, чтобы решить эту проблему:

class A{}

class B extends A{}

interface I{
 // expects object instanceof A
 function doSomething(A $a);
}

class C implements I
{

 function doSomething(A $b){
   if($b is instance of B){
   //do something
   }else{throw new InvalidArgumentException("arg must be instance of B") };
 }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...