Bug #67232 [Nab]: Interface inheritence not possible in interface
| From: | tyrael@php.net | Date: | Fri, 09 May 2014 09:09:06 +0000 |
| Subject: | Bug #67232 [Nab]: Interface inheritence not possible in interface | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-185740@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=67232&edit=1
ID: 67232
Updated by: tyrael@php.net
Reported by: r dot van dot bezooijen at factua dot nl
Summary: Interface inheritence not possible in interface
Status: Not a bug
Type: Bug
Package: Scripting Engine problem
Operating System: Linux
PHP Version: 5.4.28
Block user comment: N
Private report: N
New Comment:
"then objects of type T(IVisitee) in a program may be replaced with objects of type
S(IMetadata) without altering any of the desirable properties of that program"
the typehint of accept() of T and S isn't compatible (eg. S accepts only a subset of what T
accepts), so when changing T-s with S your program would/could start throwing E_RECOVERABLE_FATALs
about wrong argument passed.
Previous Comments:
------------------------------------------------------------------------
[2014-05-09 06:21:05] r dot van dot bezooijen at factua dot nl
shouldnt this implicate that it should be possible?
------------------------------------------------------------------------
[2014-05-09 06:18:57] r dot van dot bezooijen at factua dot nl
You are correct about LSP, but if i replace S & T with my class i get this:
{quote}
if S(IMetadata) is a subtype of T(IVisitee), then objects of type T(IVisitee) in a program may be
replaced with objects of type S(IMetadata) without altering any of the desirable properties of that
program
{quote}
------------------------------------------------------------------------
[2014-05-08 12:50:39] tyrael@php.net
43200 isn't related to this as far as I can see.
I think php is doing the right thing here.
When extending IVisitee, you are trying to change the signature of accept:
IVisitee would accept any class implementing IVisitor, while your IMetadata now would only accept
objects implementing IValidatorVisitor, which are only a subset of classes implemting IVisitor.
The Liskov substitution principle defines that "if S is a subtype of T, then objects of type T
in a program may be replaced with objects of type S without altering any of the desirable properties
of that program (e.g., correctness).".
Your example breaks LSP, IMetadata can't always replace IVisitee, as the method signature for
accept is different (btw same deal with IValidatorVisitor and IVisitor).
At least this is my understanding of the situation.
------------------------------------------------------------------------
[2014-05-08 07:17:49] r dot van dot bezooijen at factua dot nl
Description:
------------
when overriding and interface method in another interface it's says they are incompatible with
eachother while the overriding method contains a class/interface which is extended from the
class/interface defined in the parent
I think its also related to bug report 43200, Although it's not exactly the same problem.
Test script:
---------------
<?php
interface IVisitee
{
public function accept( IVisitor $visitor );
}
interface IVisitor
{
public function visit( IVisitee $visitee );
}
interface IMetadata extends IVisitee
{
public function accept( IValidatorVisitor $visitor );
public function findConstraints( $group );
}
interface IValidatorVisitor extends IVisitor
{
public function validate( $group, $transverse = false, $deep = false );
public function visit( IMetadata $visitee );
}
Actual result:
--------------
PHP Fatal error: Declaration of IMetadata::accept() must be compatible with
IVisitee::accept(IVisitor $visitor) in /tmp/test.php on line 30
PHP Stack trace:
PHP 1. {main}() /tmp/test.php:0
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=67232&edit=1