Bug #67232 [Nab]: Interface inheritence not possible in interface

From: 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

« previous php.bugs (#185740) next »