>> do you know any reason for this? >> > > The reason for this is simply that B must act like A since every B object is > also an object of A. > >
The reason for restricting the method signature in the Subclass is to guarantee that an instance of a Subclass should work where an instance of the Superclass is expected. I think that this can be achieved with much weaker rules than expecting that the method in the Subclass has the exact signature as the Superclass. For example we do allow overriding visibility, but only weakening it(eg. private->protected or protected->public is allowed but public->protected isn't), else there could be cases where using the instance of the Superclass works, but the Subclass won't. Another thing that we should take into account: php is no java, so we don't have to require exactly matching method signature, as in php the method name cannot be ambiguous(we don't support declaring methods with the same name but different argument signature), and because of this passing more arguments than it was declared also supported in the userland functions/methods. So based on this, the following cases are which would make a Subclass incompatible with it's Superclass: - tightening visibility (we already restrict this) - declaring more arguments in the Subclass than in the Superclass, and having no default value for those. - declaring different typehints in the Subclass than it was declared in the Superclass. theoretically we could also allow changing the typehinting where it makes sense (for example it would be safe to allow changing the typehint from Foo to Bar if Bar extends/implements Foo), but I think that would require too much work, so I'm fine with requiring the same typehint if it was present in the parent. - removing default values from the arguments. (declaring the same argument as in the Superclass, but without default value, while the Superclass declared it with default value) the following cases would be allowed to change the method signature without making the Subclass incompatible with it's Superclass: - the Subclass could declare fewer arguments than it's Superclass. this could sound wrong, but as I mentioned, the engine allows passing more arguments, than it was declared, so Subclass would work everywhere where the Superclass is expected, and the arguments can be accessed through func_get_args. of course it would allow someone to shot himself in the foot(if he chose not to fetch the arguments from the method body), but that can happen already(for example. the Subclass can return different type than what the Superclass would, or it could throw different Exceptions, or just return some bogus value, etc.). - the Subclass could declare more argument than it's Superclass, as long, as the additional argument are having default values. - the Subclass could declare arguments without typehints which were declared with typehints in the Superclass. - the Subclass could declare arguments with default values which were declared without default values in the Superclass. for example: class super{ public function init(array $a=null){ } } could be extended like: // one additional argument, but it has default value, so it is fine class sub extends super{ public function init(array $a=null, $b=false){ } } // same argument but without the typehint class sub extends super{ public function init($a=null){ } } // fewer arguments class sub extends super{ public function init(){ } } // remove the typehint class sub extends super{ public function init($a=null){ } } but the followings are all invalid: // invalid, because it removes the default value class sub extends super{ public function init(array $a){ } } // invalid, because the additional argument doesn't have a default value class sub extends super{ public function init(array $a, $b){ } } // invalid, because changes the typehint class sub extends super{ public function init(StdClass $a, $b){ } } ps: the invalid signature should generate catchable fatal error, not fatal error imo, we are using fatal error many places where it would be reasonable to use Catchable fatal error, as Fatals should be only used where the Engine is left in an unstable state, or which cannot be recovered from. -- Ferenc Kovács @Tyr43l - http://tyrael.hu -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php