Ankündigung

Einklappen
Keine Ankündigung bisher.

[Erledigt] strict, hinting & inheritance

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • [Erledigt] strict, hinting & inheritance

    Moin moin,

    kleine Diskussion zum Wochenende. Ich frage mich gerade, wie ich Type Hinting und Vererbung unter einen Hut bekomme. Da PHP kein Methoden-Overloading beherrscht, bekomme ich immer nette Strict-Fehler. Das ist zwar nicht dramatisch, ich will aber trotzdem schönen Code produzieren.
    Hier mal ein Beispiel:

    PHP-Code:
    <?php


    interface myElementIface 
      
    {
      }

    interface 
    mySpecialElementIface 
      
    {
      function 
    doSpecial (); 
      }


    class 
    myElement implements myElementIface 
      
    {
      function 
    doSmthg ()
        {
        }
      }

    class 
    myElementGroup 
      
    {
      function 
    addElement (myElementIface $element)
        {
        }
      }

    class 
    mySpecialElement extends myElement implements mySpecialElementIface 
      
    {
      function 
    doSpecial ()
        {
        }
      }

    class 
    mySpecialElementGroup extends myElementGroup 
      
    {
      function 
    addElement (mySpecialElementIface $element// wird einen Stict-Error erzeugen
        
    {
        
    parent::addElement ($element);
        
    $element->doSpecial ();
        }
      }
    So. Wie löst Ihr solche Probleme? Assertions? instanceof und Exceptions? Strict-Error Ignorieren? Irgendwie ist ja Vererbung bzw. Hinting sonst nicht viel wert, oder?
    Mein konkreter Anwendungsfall ist die ABbildung von Formularelementen auf entspr. Zugriffsobjekte. myElementIface könnte hier ein Formular-Basiselement repräsentieren und mySpecialElementIface z.B. ein Radiobox-Element mit eigenen Eigeneschaften.
    --

    „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
    Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“


    --


  • #2
    Dann macht doch einfach eine "abstract class myElementGroupAbstract" die diese methode nicht hat und implementiere die dann nur in den kindklassen, dann kannst du in jeder kindklasse konkret implementieren mit passendem typehint.
    robo47.net - Blog, Codeschnipsel und mehr
    | Caching-Klassen und Opcode Caches in php | Robo47 Components - PHP Library extending Zend Framework

    Kommentar


    • #3
      Naja, das Problem ist, dass gerade diese Methode (oben addElement) ja auschlaggebend für die Gruppierung ist. Über ein Interface kann ich addElement nicht als Pflichtmethode definieren (weil die Methodensignatur dann nicht übereinstimmt), deshalb der Weg über Vererbung.
      --

      „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
      Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“


      --

      Kommentar


      • #4
        Also bei mir wirft das keinen Strict-Fehler. Welche PHP-Version nutzt du denn? 5.3.x?
        Da es bei mir keinen Fehler wirft, kann ich es nicht testen, aber vielleicht hilft ja das:
        PHP-Code:
        interface mySpecialElementIface extends myElementIface
          
        {
          function 
        doSpecial (); 
          } 
        Refining Linux: “Performing Push Backups – Part 1: rdiff-backup

        Kommentar


        • #5
          5.2.5
          strict standards: Declaration of myspecialelementgroup::addelement() should be compatible with that of myelementgroup::addelement() in d:\workspace\web\test\inherit.php on line 42
          extends myElementIface bringt leider nichts. Wusste nichtmal, dass das geht Ist aber auch relativ nutzlos in meinem Fall, weil die Interfaces verschiedene Eigenschaften der Objekte repräsentieren müssen. Ich könnte dort ohnehin keine Vererbungshierarchie abbilden.

          PS:
          Unter 5.3.1 bekomme ich die selbe Meldung..
          --

          „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
          Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“


          --

          Kommentar


          • #6
            Hmm. Ich habe 5.2.12 und bekomme nichts. Ich habe auch schon
            PHP-Code:
            date('Y'); 
            ausprobiert, um die Strict-Melungen zu prüfen und bekomme tatsächlich eine Meldung wegen fehlender Zeitzoneneinstellung. Funktionieren tun die Strict-Meldungen also. Eine Meldung wegen der unterschiedlichen Typehints bekomme ich nicht.
            PHP Version 5.2.12-pl0-gentoo

            Linux pc-gentoo 2.6.32-gentoo-r4 #12 SMP Wed Mar 17 17:20:17 CET 2010 x86_64
            Refining Linux: “Performing Push Backups – Part 1: rdiff-backup

            Kommentar


            • #7
              Ist ja sonderbar. Kann doch nicht wirklich an Windows liegen?!

              Hast Du sicher den aktuellen Code? Hatte den nach 10 Minuten noch geändert.

              Ich mein, das Verhalten ist ja auch nachvollziehbar. Halt nur wahnsinnig unpraktisch, wenn man was flexibles hinbekommen will.

              [edit]
              Unter 5.2.9 (hatte ich auch noch da) gibts keine strict Meldung. Jetzt müsste man nur noch wissen, ob man davon jetzt ausgehen kann, dass Type-Hints fortan nicht zur Methodensignatur gehören.
              --

              „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
              Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“


              --

              Kommentar


              • #8
                Hallo nikosch,

                selben Blödsinn hatte ich schon im APF mit den Filtern. Hier war die Lösung, dass die Signatur der Methoden exakt gleich sein muss (auch Namen der Parameter etc). Das ist bei dir nicht der Fall. Versuche das mal auf einen generischen Typen oder Interfaces abzubilden, dann sollte es funktionieren. Siehe auch PHP :: Bug #48804 :: Overriding results in declaration error.
                Viele Grüße,
                Dr.E.

                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                1. Think about software design before you start to write code!
                2. Discuss and review it together with experts!
                3. Choose good tools (-> Adventure PHP Framework (APF))!
                4. Write clean and reusable software only!
                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

                Kommentar


                • #9
                  Versuche das mal auf einen generischen Typen oder Interfaces abzubilden, dann sollte es funktionieren.
                  Kannst Du zum ersten bitte noch einen Satz verlieren? Verstehe nicht genau, was Du meinst.
                  Mit Interfaces habe ich eher die Befürchtung, dass alles nur noch schlimmer wird. Bin auch nicht ganz sicher, ob es der selbe Bug ist, schliesslich verwende ich ja auch zwei verschiedene Type-Hints für voneinander abgeleitete Methoden.. Nen Fatal error bekomme ich auch nicht. Nur eben ne Strict-Warnung.

                  PS: Bei Deiner Bugmeldung kann ich mir gut vorstellen, dass das am fehlenden Defaultwert für $content gelegen hat, nicht am Variablennamen. Mit solchen „Kleinigkeiten“ habe ich mich ja fast schon abgefunden ..

                  [edit] Hust. Steht ja auch in der Antwort. Mist
                  --

                  „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
                  Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“


                  --

                  Kommentar


                  • #10
                    Und so sieht ---die--- eine Lösung aus (elegant geht aber anders):

                    PHP-Code:
                    class mySpecialElementGroup extends myElementGroup /*implements myElementGroupIface*/
                      
                    {
                      function 
                    addElement (myElementIface $element
                        {
                        return (
                    $this->addSpecialElement ($element));
                        }

                      function 
                    addSpecialElement (mySpecialElementIface $element// speziellen Typ hier angeben.
                        
                    {
                        
                    parent::addElement ($element);
                        
                    $element->doSpecial ();
                        }
                      } 
                    Schön ist wiederum, dass ich jetzt für mySpecialElementGroup und myElementGroup ein gemeinsames Interface mit der Methode addElement definieren kann, die den allgemeinsten Elementtyp (myElement) als Type-Hint verwendet. Ich glaube, dafür nehme ich die Krücke in Kauf.
                    --

                    „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
                    Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“


                    --

                    Kommentar


                    • #11
                      Ergänzung meines Selbstgesprächs . Die endgúltige Lösung sieht jetzt so aus:

                      PHP-Code:
                      <?php


                      interface myElementIface 
                        
                      {
                        }

                      interface 
                      mySpecialElementIface 
                        
                      {
                        function 
                      doSpecial (); 
                        }

                      interface 
                      myElementGroupIface 
                        
                      {
                        function 
                      addElement (myElementIface $element); 
                        }



                      class 
                      myElement implements myElementIface 
                        
                      {
                        function 
                      doSmthg ()
                          {
                          }
                        }

                      class 
                      myElementGroup implements myElementGroupIface
                        
                      {
                        function 
                      addElement (myElementIface $element)
                          {
                          }
                        }

                      class 
                      mySpecialElement extends myElement implements mySpecialElementIface 
                        
                      {
                        function 
                      doSpecial ()
                          {
                          }
                        }

                      class 
                      mySpecialElementGroup extends myElementGroup // (implizit: implements myElementGroupIface)
                        
                      {
                        function 
                      addElement (myElementIface $element
                          {
                          
                      parent::addElement ($this->filterType ($element));
                          
                      $element->doSpecial ();
                          }

                        protected function 
                      filterType (mySpecialElementIface $element
                          {
                          return (
                      $element);
                          }
                        }
                      Wenn ich jetzt versuche, meine Spezialgruppe mit einem Simple-Element zu füttern oder andersherum bekomme ich nen schönen Catchable fatal error, wie es gewollt ist. Den liefert zwar die filterType-Methode, nicht addElement selbst, aber wer will schon pingelig sein

                      Korrektur: myElementGroup kann natürlich auch ein mySpecialElement aufnehmen. Es bedient ja durch die Vererbung das myElement-Interface. „oder andersherum“ war also Quatsch.
                      --

                      „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
                      Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“


                      --

                      Kommentar


                      • #12
                        Hallo nikosch,

                        so meinte ich die Lösung zu implementieren. Das ist zwar blöd, dass man in einer Implementierung keine speziellen Typen hinsichtlich der Implementierung selbst vergeben kann, aber dafür müsste PHP Generics können. Ohne Generics musst du Subtype / Interfaces nutzen. Das ist auch in JAVA so.
                        Viele Grüße,
                        Dr.E.

                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                        1. Think about software design before you start to write code!
                        2. Discuss and review it together with experts!
                        3. Choose good tools (-> Adventure PHP Framework (APF))!
                        4. Write clean and reusable software only!
                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

                        Kommentar


                        • #13
                          Ok, Danke, dann hab ich ja alles richtig gemacht. Scheint bis jetzt auch ein brauchbares Konzept zu sein.
                          --

                          „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
                          Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“


                          --

                          Kommentar

                          Lädt...
                          X