Ankündigung

Einklappen
Keine Ankündigung bisher.

[Erledigt] Problem mit abstrakten Methoden in Traits

Einklappen

Neue Werbung 2019

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

  • [Erledigt] Problem mit abstrakten Methoden in Traits

    Hallo,

    ich habe ein Problem mit abstrakten Methoden innerhalb von Traits und komme nicht weiter.

    Ich habe 2 Traits, in denen jeweils eine abstrakte Methode enthalten ist. Beide abstrakten Methoden haben den gleichen Namen. Um sie in meiner Klasse "schöner" verfügbar zu machen, habe ich noch einen "Hilfs-Trait" zugefügt. Hier möchte ich den beiden gleichnamigen abstrakten Methoden unterschiedliche Namen geben. Die Implementierung der abstrakten Methoden soll jedoch erst in der Klasse statt finden (oder später sogar in abgeleiteten Klassen, z.B. LangsamesAuto, SchnellesAuto).

    Hier der (nicht lauffähige) Code:

    PHP-Code:
    trait Bremse {
        
        abstract public function 
    gibMeldung();
        
        public function 
    bremsen() {
            echo 
    "Ich bremse ...<br />";
        }
    }

    trait 
    Beleuchtung {
        
        abstract public function 
    gibMeldung();
        
        public function 
    blinken() {
            echo 
    "Ich blinke ...<br />";
        }
    }

    trait 
    HilfTrait {
        
        use 
    BremseBeleuchtung {
            
            
    Bremse::bremsen as autoBremsen;
            
    Beleuchtung::blinken as autoBlinken;
            
            
    Bremse::gibMeldung as bremseGibMeldung;
            
    Beleuchtung::gibMeldung as beleuchtungGibMeldung;
        }
    }

    class 
    Auto {
        
        use 
    HilfTrait;
        
        public function 
    bremseGibMeldung() {
            echo 
    "Meldung von der Bremse.<br />";
        }
        
        public function 
    beleuchtungGibMeldung() {
            echo 
    "Meldung von der Beleuchtung.<br />";
        }
        
        public function 
    beschleunigen() {
            echo 
    "Ich beschleunige ...<br />";
        }
    }

    $auto = new Auto();
    $auto->beschleunigen();
    $auto->autoBremsen();
    $auto->autoBlinken();
    $auto->bremseGibMeldung();
    $auto->beleuchtungGibMeldung(); 


  • #2
    Abstrakte Methoden die in Traits definiert werden aber in der nutzenden Klasse implementiert werden sollen überschreiben das Trait und beachten es nicht, die Abstrakte Methode ist also Sinnlos.
    [URL="https://gitter.im/php-de/chat?utm_source=share-link&utm_medium=link&utm_campaign=share-link"]PHP.de Gitter.im Chat[/URL] - [URL="https://raindrop.io/user/32178"]Meine öffentlichen Bookmarks[/URL] ← Ich habe dir geholfen ? [B][URL="https://www.amazon.de/gp/wishlist/348FHGUZWTNL0"]Beschenk mich[/URL][/B].

    Kommentar


    • #3
      Puh ... Dadurch macht jetzt auch die Fehlermeldung sinn.
      Aber wie kann ich sonst Mehrfachvererbung von abstrakten Methoden realisieren, die in verschiedenen "Behältern" enthalten sind und u.u. den gleichen Namen haben?

      Kommentar


      • #4
        Die frage ist ob du das musst. Warum stellst du keine Interface davor und legst dort den prototyp fest ?

        Im Endeffekt abstrahierst du ja nur die Methoden-Signatur, das leistet auch ein Interface.
        [URL="https://gitter.im/php-de/chat?utm_source=share-link&utm_medium=link&utm_campaign=share-link"]PHP.de Gitter.im Chat[/URL] - [URL="https://raindrop.io/user/32178"]Meine öffentlichen Bookmarks[/URL] ← Ich habe dir geholfen ? [B][URL="https://www.amazon.de/gp/wishlist/348FHGUZWTNL0"]Beschenk mich[/URL][/B].

        Kommentar


        • #5
          Da hast du recht. Ich probiere das gerade aus.

          Kann man das verallgemeinern? Also ... wenn Methoden-Signaturen vererbt werden sollen benutzt man interfaces, und wenn Methoden mit Implementierung vererbt werden sollen benutzt man Traits?

          Kommentar


          • #6
            Die Kurzform:

            Traits nutzt man wenn man wiederholende Logik einer oder mehrerer Methoden gruppieren will. Traits kann man nutzen wenn man sonst sehr lange klassen in Segmente teilen möchte. Traits sind ein Werkzeug zur Vererbung von Methoden an mehrere Klassen.

            Interfaces nutzt man wenn man festlegen möchte wie eine Klasse auszusehen hat und/oder die Implementierung vom Klassen-Design loslösen möchte.
            [URL="https://gitter.im/php-de/chat?utm_source=share-link&utm_medium=link&utm_campaign=share-link"]PHP.de Gitter.im Chat[/URL] - [URL="https://raindrop.io/user/32178"]Meine öffentlichen Bookmarks[/URL] ← Ich habe dir geholfen ? [B][URL="https://www.amazon.de/gp/wishlist/348FHGUZWTNL0"]Beschenk mich[/URL][/B].

            Kommentar


            • #7
              Perfekt Das war der fehlende Baustein in meinem Verständnis.
              Vielen Dank

              Kommentar


              • #8
                Übrigens: Es ist immer besser eine Problemdomäne nach Zuständigkeiten zu zerteilen, statt sie über Traits nur in einem großen Objekt verteilen. Es gibt nur sehr wenige gute Gründe für Traits. Normal fährst du immer besser, wenn du möglichst kleine Klassen mit wenigen Methoden entwirfst, die für ein simples Problem eine simple Lösung haben.

                Für dein Beispiel würde das folgendes Bedeuten:

                Das Auto ist ein Composite. Es kapselt verschiedene, für sich selbst gesehen aber eigenständige Objekte, die lose miteinander verbunden werden können. Zum Beispiel das Licht. Nimmt ein VW-Golf als Beispiel. Die hier verbauten Teile lassen sich zu einem großen Teil auch in anderen Modellen des Konzerns verbauen - neben den Teilen, die ohnehin genormte Schnittstellen haben.

                So kannst du die einzelnen Probleme nachher in individuellen Klassen separat Lösen und dem Auto als Dependency injizieren (denke schnell an Autoradio, Reifen, Motor, Lampen, Lenkrad, Türen, Sitze...). So "kommuniziert" das Auto mit seinen Einzelteilen nur noch über Schnittstellen, die du im späteren Verlauf des Lebenszyklus eines Autos (bzw. deiner Anwendung) gegen neue, bessere Teile ersetzen kannst, ohne die gleich ein neues Auto kaufen/bauen zu müssen . Und diese Schnittstellen können bei Software alles sein - denn Software ist kein Gegenstand der physischen Gesetzen widerstehen muss.
                Standards - Best Practices - AwesomePHP - Guideline für WebApps

                Kommentar


                • #9
                  Vielen Dank rkr. Das sind wirklich gute Tipps. Ich habe mich eben in ein paar Sachen eingelesen, habe es dann aber sein gelassen, weil ich mich erst seit 2 Tagen mit PHP beschäftige. Die ersten Gehversuche mit Entwurfsmuster habe ich für das kommende Wochenende geplant. Mit schön viel Kaffee

                  Ich habe das Beispiel mal angepasst. Vielleicht ist ja hier sonst noch jemand daran interessiert.
                  In einem Trait habe ich auch eine abstrakte Methode eingebaut, um den Benutzer der Klasse "zu zwingen" die Methode zu implementieren.
                  Ist einfach nur ein Stück Beispielcode ...

                  PHP-Code:
                  trait Bremse {
                      
                      abstract public function 
                  gibBremsentyp();
                      
                      public function 
                  gibMeldung() {
                          echo 
                  "Meldung von der Bremse.<br />";
                      }
                      
                      public function 
                  bremsen() {
                          echo 
                  "Ich bremse ...<br />";
                      }
                  }

                  trait 
                  Beleuchtung {
                      
                      public function 
                  gibMeldung() {
                          echo 
                  "Meldung von der Beleuchtung.<br />";
                      }
                      
                      public function 
                  blinken() {
                          echo 
                  "Ich blinke ...<br />";
                      }
                      
                      public function 
                  gibHinweis () {
                          echo 
                  "Beim fahren besser Licht einschalten !!!<br />";
                      }
                  }


                  trait 
                  HilfTrait {
                      
                      use 
                  BremseBeleuchtung {
                          
                          
                  Bremse::gibMeldung insteadof Beleuchtung;
                          
                  Bremse::gibMeldung as bremseGibMeldung;
                          
                  Beleuchtung::gibMeldung as beleuchtungGibMeldung;
                          
                  Beleuchtung::gibHinweis as private;
                      }
                  }

                  class 
                  Auto {
                      
                      use 
                  HilfTrait;
                      
                      public function 
                  gibBremsentyp() {
                          echo 
                  "Spassbremse 2.0<br />";
                      }
                      
                      public function 
                  beschleunigen() {
                          echo 
                  "Ich beschleunige ...<br />";
                          
                  $this->gibHinweis();
                      }
                  }

                  $auto = new Auto();
                  $auto->beschleunigen();
                  $auto->bremsen();
                  $auto->gibBremsentyp();
                  $auto->blinken();
                  $auto->bremseGibMeldung();
                  $auto->beleuchtungGibMeldung(); 

                  Kommentar

                  Lädt...
                  X