Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > de.comp.lang.php > #3856

Re: return types

From Thomas 'PointedEars' Lahn <PointedEars@web.de>
Newsgroups de.comp.lang.php
Subject Re: return types
Date 2016-04-02 20:33 +0200
Organization PointedEars Software (PES)
Message-ID <6322257.QELA2EPoA3@PointedEars.de> (permalink)
References <1t56fced94i14b9n3e8%sfroehli@Froehlich.Priv.at> <3243755.WBM996tjSl@PointedEars.de> <dm7lpsFpt1jU1@mid.individual.net>

Show all headers | View raw


Stefan Froehlich wrote:

> On Thu, 31 Mar 2016 21:40:04 Thomas 'PointedEars' Lahn wrote:
>> > class Foo {
>> >         public function cloneMe() : Foo {
>> >                 return clone $this;
>> >         }
>> > }
>> > 
>> > 
>> > class Foo_Child extends Foo {
>> >         public function cloneMe() : Foo_Child {
>> >                 return clone $this;
>> >         }
>> > }
>> > ?>
>> > #v-
>> > 
>> > führt zu:
>> > 
>> > | PHP Fatal error:  Declaration of Foo_Child::cloneMe(): Foo_Child must
>> > | be compatible with Foo::cloneMe(): Foo in /home/sfroehli/test.php on
>> > | line 13
> 
>> > Dass die Signaturen kompatibel sein müssen ist klar,
> 
>> Ich finde auch das zu eng gedacht.
> 
> Stimmt, *müssen* tun sie es nicht. Allerdings:
> 
>> Wenn ich eine Methode überschreiben kann, sollte ich das auf beliebige
>> Art tun können. Polymorphismus impliziert nicht, dass Gleichbenanntes
>> auch gleich funktionieren muss; denn ich kann die Klasse eines Objekts
>> ermitteln und die polymorphe Methode so aufrufen, wie es für die
>> jeweilige Klasse korrekt ist.
> 
> Ich persönlich möchte, wenn ich lese:
> 
> #v+
> abstract class Foo {
> public function bar(int $b) : int;
> }
> #v-
> 
> ...auch *garantiert* das folgende fehlerfrei tun können:
> 
> #v+
> if ($f instanceof Foo) $b2 = $f->bar($b1);
> #v-
> 
> ...und nicht womöglich daran scheitern, dass die abgeleitete Klasse
> Foo_Bar die Methode womöglich ganz anders definiert hat.
> 
> Das geht aber nur dann, wenn mir nicht jemand die Signatur dieser
> Methode unter dem Hintern wegziehen kann.

ACK.  “instanceof” überprüft aber _nicht_, ob ein Objekt eine Instanz einer 
bestimmten Klasse ist.  Ich meinte deshalb get_class().

> Allerdings würde ich mir gelegentlich das wünschen, was ich bei C++ so
> geschätzt habe, z.B.:
> 
> #v+
> abstract class Foo {
> public function bar(Array $a) : int;
> public function bar(Collection $c) : int;
> }
> #v-
> 
> Es geht allerdings - wenn überhaupt - nur eines von beiden: Entweder
> überschreiben Methoden diejenigen ihrer Elternklasse unabhängig von
> den verwendeten Parametern, oder halt nicht.

Die aus C++ bekannte Funktionalität ist in PHP vorhanden, aber entweder 
müssen die Klassen voneinander abgeleitet sein oder die Typüberprüfung muss 
manuell implementiert werden.  Entweder

  $foo instanceof ArrayObject === $foo instanceof Collection /* [1] */

dann

  public function bar (ArrayObject $c) : int;

(wenn man davon ausgeht, dass eine Collection eine Spezialisierung eines 
ArrayObjects ist), oder

  public function bar (ArrayAccess $c) : int
  {
    if (!($c instanceof ArrayObject || $c instanceof Collection))
    {
      throw new \InvalidArgumentException('ArrayObject or Collection 
expected.');
    }
  }

wenn man davon ausgeht, dass sowohl ArrayObject als auch Collection das 
ArrayAccess-Interface implementieren, ohne voneinander abgeleitet zu sein.

Was nicht zum Ziel führt, ist

  public function bar (object $c) : int
  {
    /* … */
  }

denn es gibt keine Klasse “object”; ebenso führt “stdClass” statt “object” 
nicht zum Ziel, obwohl es diese Klasse gibt.  Stattdessen muss (wie von 
Christoph vorgeschlagen) die Methode ohne Parameter deklariert werden, und 
der Zugriff auf Argumente mit func_*_param*() vorgenommen werden; eine 
Typüberprüfung muss dann in der Methode stattfinden.

Auch hier erscheint mir das PHP-Typsystem und Type Hinting/Declaration in 
PHP nicht zuende gedacht: da

  (object) $foo

zu einer Referenz auf eine Instanz von “stdClass” konvertiert, sollten alle 
PHP-Klassen implizit von “stdClass” (oder noch besser neu von einer 
“object”-Klasse, vgl. Python) abgeleitet sein.  Jedoch z. B.

  (new ArrayObject()) instanceof stdClass === false

________
[1] “Array” ist wegen Nichtbeachtung von Gross-/Klein-Schreibung kein
    zulässiger Klassenname.
-- 
PointedEars
Zend Certified PHP Engineer 
<http://www.zend.com/en/yellow-pages/ZEND024953> | Twitter: @PointedEars2
Please do not cc me. / Bitte keine Kopien per E-Mail.

Back to de.comp.lang.php | Previous | NextPrevious in thread | Next in thread | Find similar


Thread

return types Stefan+Usenet@Froehlich.Priv.at (Stefan Froehlich) - 2016-03-31 09:35 +0000
  Re: return types k@rl.pflaesterer.de (Karl Pflästerer) - 2016-03-31 12:42 +0200
  Re: return types "Christoph M. Becker" <cmbecker69@arcor.de> - 2016-03-31 14:16 +0200
    Re: return types Stefan+Usenet@Froehlich.Priv.at (Stefan Froehlich) - 2016-04-15 06:37 +0000
    Re: return types Stefan+Usenet@Froehlich.Priv.at (Stefan Froehlich) - 2016-06-22 08:48 +0000
      Re: return types "Christoph M. Becker" <cmbecker69@arcor.de> - 2016-06-22 12:25 +0200
        Re: return types Stefan+Usenet@Froehlich.Priv.at (Stefan Froehlich) - 2016-06-22 14:49 +0000
          Re: return types "Christoph M. Becker" <cmbecker69@arcor.de> - 2016-06-22 17:47 +0200
            Re: return types Stefan+Usenet@Froehlich.Priv.at (Stefan Froehlich) - 2016-06-23 08:23 +0000
              Re: return types "Christoph M. Becker" <cmbecker69@arcor.de> - 2016-07-02 01:03 +0200
  Re: return types Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2016-03-31 21:40 +0200
    Re: return types Stefan+Usenet@Froehlich.Priv.at (Stefan Froehlich) - 2016-04-01 16:26 +0000
      Re: return types "Christoph M. Becker" <cmbecker69@arcor.de> - 2016-04-02 19:23 +0200
        Re: return types Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2016-04-02 20:36 +0200
        Re: return types Stefan+Usenet@Froehlich.Priv.at (Stefan Froehlich) - 2016-04-11 21:18 +0000
      Re: return types Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2016-04-02 20:33 +0200
        Re: return types Stefan+Usenet@Froehlich.Priv.at (Stefan Froehlich) - 2016-04-11 21:32 +0000
          Re: return types Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2016-04-19 20:24 +0200
            Re: return types Stefan+Usenet@Froehlich.Priv.at (Stefan Froehlich) - 2016-04-20 07:05 +0000
              Re: return types Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2016-04-21 02:55 +0200

csiph-web