Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:8135 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 15707 invoked by uid 1010); 26 Feb 2004 00:40:15 -0000 Delivered-To: ezmlm-scan-internals@lists.php.net Delivered-To: ezmlm-internals@lists.php.net Received: (qmail 15683 invoked from network); 26 Feb 2004 00:40:15 -0000 Received: from unknown (HELO shiva.mind.de) (212.42.230.204) by pb1.pair.com with SMTP; 26 Feb 2004 00:40:15 -0000 Received: from [192.168.1.105] (p508EBE6F.dip.t-dialin.net [80.142.190.111]) by shiva.mind.de (Postfix) with ESMTP id 43DA397B59; Thu, 26 Feb 2004 01:40:09 +0100 (CET) Date: Thu, 26 Feb 2004 01:38:08 +0100 Reply-To: Marcus Boerger X-Priority: 3 (Normal) Message-ID: <1721299626562.20040226013808@marcus-boerger.de> To: Timm Friebe Cc: internals@lists.php.net In-Reply-To: <1077752071.685.57.camel@localhost> References: <1077748616.685.16.camel@localhost> <1781292779406.20040225234401@marcus-boerger.de> <1077749539.685.27.camel@localhost> <1077752071.685.57.camel@localhost> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Subject: Re: [PHP-DEV] Declaration of Bar::__construct() must be compatible with that of Foo::__construct() From: helly@php.net (Marcus Boerger) Hello Timm, Thursday, February 26, 2004, 12:34:31 AM, you wrote: > On Wed, 2004-02-25 at 23:52, Timm Friebe wrote: >> On Wed, 2004-02-25 at 23:44, Marcus Boerger wrote: >> > Hello Timm, >> > >> > i had the same expirience today too. And also for me it makes not much >> > sense. The constructor shouldn't check inheritance rules. >> >> Neither should other methods follow this. What if I want to add a >> non-default parameter to an overriden method? > Some test cases: > 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. > ------------------------------------------------------------------- > interface Connector { > function connect($server); > } > class Foo implements Connector { > function connect($server) { } > } > class Bar extends Foo { > function connect($server, $port) { } > } ?>> > Should work #2, Bar::connect() might contain something such as Same asas above > parent::connect('foo.example.com'); > ------------------------------------------------------------------- > interface Connector { > function connect($server); > } > class Foo implements Connector { > function connect($server) { } > } > class Bar extends Foo { > function connect() { } > } ?>> > Should work #3, Bar::connect() might contain something such as Same as above. Foo::connect() can be called with any value Bar::connect() not. > parent::connect($dsn->getHost()); > ------------------------------------------------------------------- > class DSN { } > interface Connector { > function connect($server); > } > class Foo implements Connector { > function connect($server) { } > } > class Bar extends Foo { > function connect(DSN $dsn) { } > } ?>> > Should work #4, Foo::connect() adds a default argument Should work, since the calling convention from Connector is still possible in Foo and Bar. Hence Foo::connect() IS-A Connector::connect() and Bar::connect() IS-A Connector::connect(). > ------------------------------------------------------------------- > interface Connector { > function connect($server); > } > class Foo implements Connector { > function connect($server, $port= 42) { } > } > class Bar extends Foo { > function connect($server, $port= 23) { } > } ?>> > Should work #5, both interface and implementer have a default value > for the argument "server" Should work. Connector's calling convention is till valid in Bar. Hence Foo::connect() IS-A Connector::connect() and Bar::connect() IS-A Connector::connect(). > ------------------------------------------------------------------- > interface Connector { > function connect($server= 'localhost'); > } > class Foo implements Connector { > function connect($server= 'localhost') { } > } > class Bar extends Foo { > function connect($server= 'localhost', $port= 23) { } > } ?>> > Should work #6, implementation adds a default value Same as #5 only more complicated. > ------------------------------------------------------------------- > interface Connector { > function connect(); > } > class Foo implements Connector { > function connect($server= 'localhost') { } > } > class Bar extends Foo { > function connect($server= 'localhost', $port= 23) { } > } ?>> > Should NOT work #1, Foo doesn't fully implement connect() Right shouldn't work. > ------------------------------------------------------------------- > interface Connector { > function connect($server); > } > class Foo implements Connector { > function connect() { } > } > class Bar extends Foo { > function connect($server, $port) { } > } ?>> > 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. > ------------------------------------------------------------------- > class DSN { } > interface Connector { > function connect(DSN $dsn); > } > class Foo implements Connector { > function connect($dsn) { } > } > class Bar extends Foo { > function connect($dsn) { } > } ?>> > Should NOT work #3, Foo implements Connector::connect() incorrectly Should work. Still Foo::connect() IS-A Connector::connect() and Bar::connect() IS-A Connector::connect(). > ------------------------------------------------------------------- > interface Connector { > function connect($server); > } > class Foo implements Connector { > function connect($server, $port) { } > } > class Bar extends Foo { > function connect($server, $port= 23) { } > } ?>> > Should NOT work #4, Foo implements Connector::connect() incorrectly Right, shouldn't work. Inheritance doesn't apply since the signatures are incompatible. > ------------------------------------------------------------------- > interface Connector { > function connect(); > } > class Foo implements Connector { > function connect($server) { } > } > class Bar extends Foo { > function connect($server, $port) { } > } ?>> > I would simply refrain from calling > zend_do_perform_implementation_check() in inheritance. > - Timm -- Best regards, Marcus mailto:helly@php.net