On Thu, 2004-02-26 at 01:38, Marcus Boerger wrote: > Hello Timm, [...] > > Should work #1, Bar::connect() adds an argument > No the sugnature is incompatible. An instance of Foo cannot be called > with Bar or Connector's connect() Signature. Hence Bar is not a Foo > or Connector.
Hrm, that's quite a (huge) BC break then. I know that adding a parameter kind-of violates the contract between Bar and Connector, but - for an instance - omit the interface idea and think about this: class Error { function __construct($message) { } } class SQLError extends Error { function __construct($message, $sql) { } } This gives us an error. Or, not to restrict this to constructors: class Printer { function print() { } } class MultipleFormatCapablePrinter extends Printer { function print($format) { } } This works just fine in PHP4, where, if I call SQLError's constructor with one argument only, I'll simply get an E_WARNING. You're changing this to a E_COMPILE_ERROR. Shouldn't some alarm bells start ringing here? With this new requirement, I'd have to make all additional parameters optional in subclasses. This introduces more kludges: class MultipleFormatCapablePrinter extends Printer { function print($format= NULL) { if (NULL === $format) { throw new IllegalArgumentException('Format may not be NULL'); } } } Now users can call this method (they could find out, e.g., via Reflection_Method that format is an *optional* parameter - which means: it can be ommitted, and if it is, it'll just be NULL - but it actually can't, it's only declared with a default value because of a language requirement) and won't even get an error if I don't catch it myself. This doesn't come up in Java, as they have method overloading, so MultipleFormatCapablePrinter::print() is actually a different method as Printer::print() and you get away with it. And yes, PHP isn't Java. [...] > > Should NOT work #2, class / primitive clash on argument > Wrong. Should work. Foo::connect() IS-A Connector::connect() and > Bar::connect() IS-A Connector::connect(). It is no problem that a > derived clsses method accepts a greater value range or set of types. Well, this one: > <?php > class DSN { } > > interface Connector { > function connect(DSN $dsn); > } > > class Foo implements Connector { > function connect($dsn) { } > } > > class Bar extends Foo { > function connect($dsn) { } > } > ?> doesn't work right now, see zend_compile.c, lines 1737 - 1744. There's even an inline comment (!) about it there:) Even more weirdness: [EMAIL PROTECTED]:~/devel/php/tests > cat inheritance.php <?php interface Connector { function connect(); } class Foo implements Connector { function connect($server) { } } ?> [EMAIL PROTECTED]:~/devel/php/tests > php-dev inheritance.php [EMAIL PROTECTED]:~/devel/php/tests > cat inheritance-b0rked.php <?php interface Connector { function connect($server); } class Foo implements Connector { function connect($server, $port) { } } ?> [EMAIL PROTECTED]:~/devel/php/tests > php-dev inheritance-b0rked.php Fatal error: Declaration of Foo::connect() must be compatible with that of Connector::connect() in /usr/home/thekid/devel/php/tests/inheritance-b0rked.php on line 6 Huh? So having zero arguments in the interface and one in the implementation is OK but having one in the interface and two in the implementation is not? - Timm -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php