Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:8136 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 84248 invoked by uid 1010); 26 Feb 2004 01:18:18 -0000 Delivered-To: ezmlm-scan-internals@lists.php.net Delivered-To: ezmlm-internals@lists.php.net Received: (qmail 84224 invoked from network); 26 Feb 2004 01:18:17 -0000 Received: from unknown (HELO moutng.kundenserver.de) (212.227.126.184) by pb1.pair.com with SMTP; 26 Feb 2004 01:18:17 -0000 Received: from [212.227.126.161] (helo=mrelayng.kundenserver.de) by moutng.kundenserver.de with esmtp (Exim 3.35 #1) id 1AwAAL-0003Jb-00 for internals@lists.php.net; Thu, 26 Feb 2004 02:18:17 +0100 Received: from [80.139.1.157] (helo=[80.139.1.157]) by mrelayng.kundenserver.de with asmtp (Exim 3.35 #1) id 1AwAAL-00029J-00 for internals@lists.php.net; Thu, 26 Feb 2004 02:18:17 +0100 To: internals@lists.php.net In-Reply-To: <1721299626562.20040226013808@marcus-boerger.de> References: <1077748616.685.16.camel@localhost> <1781292779406.20040225234401@marcus-boerger.de> <1077749539.685.27.camel@localhost> <1077752071.685.57.camel@localhost> <1721299626562.20040226013808@marcus-boerger.de> Content-Type: text/plain Message-ID: <1077758027.685.109.camel@localhost> Mime-Version: 1.0 X-Mailer: Ximian Evolution 1.4.4 Date: Thu, 26 Feb 2004 02:13:48 +0100 Content-Transfer-Encoding: 7bit X-Provags-ID: kundenserver.de abuse@kundenserver.de auth:e958292ea7b1c44e51b2b9ca0a9da460 Subject: Re: [PHP-DEV] Declaration of Bar::__construct() must be compatible with that of Foo::__construct() From: thekid@thekid.de (Timm Friebe) 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: > 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: thekid@friebes:~/devel/php/tests > cat inheritance.php thekid@friebes:~/devel/php/tests > php-dev inheritance.php thekid@friebes:~/devel/php/tests > cat inheritance-b0rked.php thekid@friebes:~/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