T-Rex: Abstracte Methode mit konkretem Type Hinting

Moin,

folgendes abstraktes Konstrukt hab ich da:

class cParent

class cChild extends cParent

class cExecuter
abstract public function execute( cParent $objParent )

class cExecuterDetail extends cExecuter
public function execute( cChild $objChild )

Tjo die abstrakte Methode execute erwartet ein Objekt vom Typ cParent. In der Klasse cExecuteDetail wird dieser Aufruf dann konkretisiert (zumindest ist das mein Gedanke). Laut OOP Ansatz dürfte das kein Problem darstellen. Trotzdem wirft mir PHP einen Fehler um die Ohren - "blablabla must be compatible with that of blabla".

Also eine Lösung brauch ich für das Problem eher weniger. Ich wollte einfach mal Fragen ob jemand weiß wieso das so ist? Hat PHP da vielleicht einen Denkfehler? *hust* oder ich *hust*?

Gruß
der ohne Denkfehler!
T-Rex

  1. Hi,

    class cExecuter
    abstract public function execute( cParent $objParent )

    class cExecuterDetail extends cExecuter
    public function execute( cChild $objChild )

    Der "Kontrakt" von Klasse cExecuter besagt, dass jedes Objekt dieses Typs (oder eben abgeleitet davon) eine Methode execute besitzt, welche mit einem cParent aufgerufen werden kann. cExecuterDetail verletzt diesen Kontrakt, daher ist es nicht gültig.

    Bis die Tage,
    Matti

    1. Der "Kontrakt" von Klasse cExecuter besagt, dass jedes Objekt dieses Typs (oder eben abgeleitet davon) eine Methode execute besitzt, welche mit einem cParent aufgerufen werden kann. cExecuterDetail verletzt diesen Kontrakt, daher ist es nicht gültig.

      Aber cChild ist doch eine Spezialisierung der Klasse cParent. Wenn das keine abstrakte Funktion wäre funktioniert es ja auch:

      function execute(cParent $objParent)
      $objObject->execute( $objChild )

      Da wird nicht gemeckert.

      Gruß
      Executer
      T-Rex

      1. Hi,

        Wenn das keine abstrakte Funktion wäre funktioniert es ja auch:

        function execute(cParent $objParent)
        $objObject->execute( $objChild )

        Da wird nicht gemeckert.

        Nein, da natürlich nicht - denn da lässt du ja die abstrakte Methode weg, und damit auch den Widerspruch zwischen eben dieser Vorgabe und der konkreten Implementierung.

        abstract public function execute( cParent ... )
                                          ^^^^^^^
        public function execute( cChild ... )
                                 ^^^^^^

        An den Stellen liegt der Widerspruch.
        Was du letztendlich beim Aufruf zur Laufzeit als Parameter übergibst, interessiert an dieser Stelle noch gar nicht - der Widerspruch ist schon in der Deklaration vorhanden.

        Wenn du an der zweiten Stelle auch cParent per type hinting vorgibst, dann kannst du die Methode anschließend auch problemlos mit einem Objekt vom Typ cChild aufrufen - aber eben auch mit einem cParent. Wenn letzteres aber ausgeschlossen sein soll, weil die cExecuterDetail-Methode damit nicht arbeiten kann - dann ist deine abstrakte Methodendeklaration schlicht und einfach falsch bzw. damit nicht vereinbar.

        MfG ChrisB

        --
        RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?