|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2008-11-28 07:57 UTC] wrzasq at gmail dot com
Description: ------------ It is impossible to implement multiple interfaces that declares same methods. I saw bug #43200 but this is a bit different case and I think in this situation it shoud be allowed - those interfaces requires methods with same signature (also to prevent further problems - optional parameters should also be allowed to match signatures): Reproduce code: --------------- <?php interface A { public function foo(); } interface B { public function foo(); } class C implements A, B { public function foo(){} } Expected result: ---------------- nothing, but working Actual result: -------------- Fatal error: Can't inherit abstract function B::foo() (previously declared abstract in A) in /home/wrzasq/Desktop/Www/engine/- on line 16 PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Fri Nov 28 13:00:02 2025 UTC |
Note its also not possible to redefine while adding new optional parameters <?php interface fooI { function ding(); } interface barI extends fooI { function ding($dong = null); } class bar implements barI { public function ding($dong = null) { echo 'woho: '.$dong."\n"; } } $bar = new bar; $bar->ding('yeah!');Actually it's possible, you just need to make the interfaces compatible for that: interface A { public function foo(); } interface B extends A { } and then you're done. This also prevents you from writing duplicate code ;) However if interfaces definitions can not be changed, then this is not a solution. Probably this is fixed? - See bug #43200.tklingenberg at lastflood dot net: I think you missed the point, or to rephrase it another way: the problem lies in the definition of "compatible": <?php interface A { public function foo(); } interface B { public function foo(); } class C implements A, B { public function foo(){} } ?> and <?php interface A { public function foo(); } interface A { public function foo(); } class C implements B { public function foo(){} } ?> should both be considered valid scripts because the two signatures for foo() [in interface A and interface B] do not contradict each other: it is possible to write a method that satisfies both. The same argument also holds for the example smith gave: <?php interface fooI { function ding(); } interface barI extends fooI { function ding($dong = null); } class bar implements barI { public function ding($dong = null) { echo 'woho: '.$dong."\n"; } } Note however that in this case, it would be invalid if bar implemented both fooI and barI because the two interfaces contradict each other (one expects an [optional] argument, while the other doesn't). Of course your example (already) works because you simply defined an empty interface (which is rather pointless, unless you're actually extending from several interfaces). Maybe another analogy will help. Let's suppose I define 2 interfaces, one for people, the other one for robots: <?php interface Person { public function speak(); public function walk(); } interface Robot { public function speak(); public function roll(); } ?> Now, imagine that I want to create a Humanoid class (a mix between a Person and a Robot). Quite naturally, I'd want to write something like this: <?php class Humanoid implements Person, Robot { public function speak() { echo "Hello world!"; } protected function goForward($speed) { /* ... */ } public function walk() { $this->goForward(1); } public function roll() { $this->goForward(3); } // some other methods... } ?> Unfortunately, this will give you an error such as this: "PHP Fatal error: Can't inherit abstract function Robot::speak() (previously declared abstract in Person) in Command line code on line 1" ... and that's what this bug is all about... It's a PITA when you must work with interfaces defined by other people which are compatible (ex: both force you to define a "__toString" method) and yet PHP returns a fatal error when you try to use them in your own class.I was unable to reproduce the fatal errors from my initial testcases with PHP 5.4.0RC2: php-5.4.0RC2 -r 'interface A { public function foo(); } interface B { public function foo(); } class Foo implements A,B { public function foo() {} }; $foo = new Foo;' php-5.4.0RC2 -r 'interface A { public function foo(); } interface B extends A { public function foo(); } class Foo implements B { public function foo() {} }; $foo = new Foo;' php-5.4.0RC2 -r 'interface A { public function foo(); } interface B extends A { public function foo($bar=null); } class Foo implements B { public function foo($bar=null) {} }; $foo = new Foo;' All those pass (don't raise any fatal error). So I guess the patch for #43200 that landed in 5.4.0RC2 also fixed this issue.