oop class extends vererbung / referenz

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

  • #16
    Ich hätte das eingangs dargestellte Problem so modelliert:
    PHP-Code:
    class ParentClass {
        public 
    $name;
        protected 
    $children = array();
        
        public function 
    __construct($name) {
            
    $this->name $name;
        }
        public function 
    giveBirth() {
            
    $this->children[] = new ChildClass($this->name);
        }
        public function 
    adopt(ChildClass $child) {
            
    $child->name $this->name;
            
    $this->children[] = $child;
        }
    }

    class 
    ChildClass extends ParentClass {}

    $parent = new ParentClass('Meier');
    $parent->giveBirth(); 
    Parents vererben den Namen an alle Kinder. Nicht nur die Eigenschaft an sich, sondern den aktuellen Wert.
    Wie man leicht sieht ist die ChildClass hier völlig überflüssig. Refaktoriert bleibt das übrig:
    PHP-Code:
    class HumanClass {
        public 
    $name;
        protected 
    $children = array();
        
        public function 
    __construct($name) {
            
    $this->name $name;
        }
        public function 
    giveBirth() {
            
    $this->children[] = new HumanClass($this->name);
        }
        public function 
    adopt(HumanClass $child) {
            
    $child->name $this->name;
            
    $this->children[] = $child;
        }

    Und siehe da, das ist eine Implementierung eines Prototype Pattern, giveBirth() ist die clone-Methode.

    Dein zuletzt genanntes Szenario 'settings' verlangt eher das Decorator Pattern. Denn die Anforderung "für eine besondere aufgabe gibt es zusätzliche werte" läßt sich nicht sauber mit nur einer Klasse erschlagen.

    Kommentar


    • #17
      Du verwechselst Dogmatismus mit Disziplin!!
      nö, sicher nicht.
      Nicht jede Kuh sollte auf dem Performace-Altar geopfert werden..
      Dem kann ich nur zu 100% beistimmen!
      Wer Fragen nach der Performance solcher Kinkerlitzchen stellt, der programmiert vermutlich noch nicht mal ansatzweise performant. (...) dieses Quentchen entscheidend (...)
      so einen schwachsinn habe ich lange nicht mehr gelesen. kleinvieh macht mist. viel kleinvieh macht viel mist. wer nicht programmieren kann soll dennoch wenigstens aufs kleinvieh achten dürfen, vielleicht wird ja nochmal was draus . wenn jemand pedantisch ist, sagt das noch lange nicht aus, daß er das ganze nicht im blick hat.
      welche verschiedenste Ausgaben tätigen sollen bzw. DB Inhalt in csv,pdf,jpg,xml,html verwandeln
      nein, sorry, das war vielleicht irreführend, nur ein versuch eines einfachen beispiels. es geht um die hierarchie/struktur und die methodik beim vererben/überschreiben der (objekt)werte. das settingsbeispiel ist klarer. ... mit interfaces lässt sich das meines wissens nicht (sinnvoll) bewerkstelligen, oder?
      auf Wunsch eine rudimentäre DB Klasse zeigen
      ja bitte, wenns die aufgabe besser löst jedenfalls

      @ onemorenerd : hm, machst du nicht das gleiche wie ich? und wo kommt adopt zum einsatz?
      child ist nicht überflüssig, denn hätte ich keine methoden in basis und kind, würde ich mir die objekte auch gleich sparen...
      Außerdem machst du genau das, was ich ja gerne aus der scriptebene heraushaben möchte: du weist die werte selbst zu, im beispiel sogar einzeln, da tut es dann auch das extends mit der schleife. oder hab ichs nicht verstanden?
      decorator ebenso: bei class kind { function __construct(elter $parent) { brauche ich ebenso die schleife zum wertezuweisen. außerdem habe ich so aber alle methoden von elter verloren. oder irr ich mich?

      vielleicht nochmal so:
      PHP-Code:
      class elter {
        public 
      $a 'a';
        public 
      $b 'b';
        function 
      kind() {
          
      $this->kind = new kind($this);
        }
        function 
      abc(){ echo 'abc'; }
      }

      class 
      kind extends elter {
        public 
      $b 'y';
        public 
      $c 'c';
        public 
      $d 'd';
        function 
      __construct($parent) {
          foreach (
      $parent as $k=>$v) {
            if( !
      is_object($v) && !isset($this->$k) ) { $this->$k $v; }
          }
        }
        function 
      xyz(){ echo 'xyz'; }
      }

      // würd ich gern machen
      $a = new elter();
      $a->'x';
      $a->kind();
      $a->kind->'z';
      $a->kind->abc();

      // will ich als ergebnis haben
      echo '<pre>'print_r($a); echo '</pre>'
      gibt aus: (ich habs eben mal ausgeführt, es lebe die copypaste )
      PHP-Code:
      elter Object
      (
          [
      a] => x
          
      [b] => b
          
      [kind] => kind Object
              
      (
                  [
      b] => y
                  
      [c] => c
                  
      [d] => z
                  
      [a] => a
              
      )


      wissen ist macht
      nichts wissen macht nichts

      Kommentar


      • #18
        verdammt! ist ja gar nicht das korrekte verhalten ...
        egal..
        es sollte natürlich
        PHP-Code:
        elter Object
        (
            [
        a] => x
            
        [b] => b
            
        [kind] => kind Object
                
        (
                    [
        b] => y
                    
        [c] => c
                    
        [d] => z
                    
        [a] => x
                
        )


        herauskommen...

        bäh
        Zuletzt geändert von Ichier; 31.10.2007, 15:51.
        wissen ist macht
        nichts wissen macht nichts

        Kommentar


        • #19
          Ich wüsste nicht, wann man eine solche Funktionalität bräuchte! Bisher haben mir immer noch allgemein bekannte Pattern geholfen
          Am besten findest du dich einfach damit ab, dass du deine Unterklasse so "kompliziert" initialisieren musst. Fertig werden!

          Kommentar


          • #20
            so einen schwachsinn habe ich lange nicht mehr gelesen. kleinvieh macht mist. viel kleinvieh macht viel mist. wer nicht programmieren kann soll dennoch wenigstens aufs kleinvieh achten dürfen, ...
            Nein, was wahsaga meint ist, dass man, wenn man sich an bestimmten Stellen Sorgen macht, lieber überlegen sollte ob nicht alles was man programmiert wesentlich zu langsam ist. Wenn man an einer Stelle angegelangt ist wo Performance wirklich zählt weil alles andere zum Beispiel sehr viel mehr Geld kostet weiß man entweder was schneller ist oder was nicht, weiß wie man es selber herausfindet oder sollte sich schnellst möglich ein anderes Projekt suchen.
            vielleicht nochmal so:
            Du hast ein Problem: Du möchtest eine Lösung realisieren die so weder Objektorientiert noch sonstwie sinnvoll ist. Das kannst du auch daran merken, dass dir inzwischen vier Leute andere Vorschläge gemacht haben. Diese Vorschläge gingen nicht in deine Richtung. Combie hat das sehr schön erklärt:
            Du willst dort eine Rückbezüglichkeit einbauen, welche fast nur mit PHP überhaupt möglich ist! Meist muß man Klassen VOR der Verwendung deklarieren. PHP öffnet an ettlichen Ecken und Kanten massig Möglichkeiten für Schweinereien. Deinen (meines bescheidenen Erachtens nach falschen) Weg hast du ja jetzt oft genug beschrieben.
            Du hast bisher immer noch nicht erklärt was du wirklich machen willst. Du hast für das was du bisher beschrieben hast mehrer Lösungen bekommen. Wenn du dir was überlegt hast, ignoriere einfach alle die Ahnung haben und mach das. Wenn du Hilfe erwartest erklär was du willst, schmeiß deinen Ansatz weg und setz die Vorschläge um.
            Die Regeln | rtfm | register_globals | strings | SQL-Injections | [COLOR=silver][[/COLOR][COLOR=royalblue]–[/COLOR][COLOR=silver]][/COLOR]

            Kommentar


            • #21
              auf Wunsch eine rudimentäre DB Klasse zeigen
              ....
              ja bitte, wenns die aufgabe besser löst jedenfalls
              KA, obs dein Problem löst........

              Wie schon gesagt, rudimentär, aber funktionsfähig!!
              Das Interface: idb.php
              PHP-Code:
              interface Idb
              {
                public function 
              __construct($dburl);
                public function 
              query($query);
                public function 
              fetch($res);

              Eine mysql klasse: db_mysql.php
              PHP-Code:
              class db_mysql implements Idb
              {
                private 
              $handle FALSE;
                
                public function 
              __construct($dburl)
                {
                  
              $path   parse_url($dburl);
                  
              $port   = isset($path['port'])?':'.$path['port']:'';
                  
              $server $path['host'].$port;
                  
                  
              $this->handle mysql_connect($server,$path['user'] ,$path['pass']);
                  if(
              FALSE === $this->handle) Throw new Exception(mysql_error());
                  
              $select mysql_select_db(trim($path['path'],"/"),$this->handle);
                  if(
              FALSE === $select) Throw new Exception(mysql_error());
                }

                public function 
              query($query)
                {
                  
              $res mysql_query($query,$this->handle);
                  if(
              FALSE === $res) Throw new Exception(mysql_error());
                  return 
              $res;
                }
                
                public function 
              fetch($res)
                {
                  return 
              mysql_fetch_assoc($res);
                }

              Eine sqlite Klasse: db_sqlite.php
              PHP-Code:
               class db_sqlite implements Idb
              {
                private 
              $handle FALSE;
                
                public function 
              __construct($dburl)
                {
                  
              $path parse_url($dburl);
                  
              $this->handle sqlite_open(trim($path['path'],"/"));
                  if(
              FALSE === $this->handle) Throw new Exception('Can not open: '.$dburl);
                }

                public function 
              query($query)
                {
                  
              $res sqlite_query($query,$this->handle);
                  if(
              sqlite_last_error($this->handle))
                    Throw new 
              Exception(sqlite_error_string(sqlite_last_error($this->handle)));
                  return 
              $res;
                }
                
                public function 
              fetch($res)
                {
                    return 
              sqlite_fetch_array($res,SQLITE_ASSOC);
                }

              Die Faktory Klasse: db.php
              PHP-Code:
               class db
              {
                static public function 
              factory($dburl)
                {
                  
              $path parse_url($dburl);
                  
              $type 'db_'.$path['scheme'];
                  return new 
              $type($dburl);
                }

              Der zugehörige Autoloader und ein kleines Testscript:
              PHP-Code:
              function __autoload($class_name)
              {
                   
              $class_name =  strtolower($class_name);
                   require_once 
              $class_name '.php';
              }

              try
              {
                
              // $db = db::factory('mysql://test:test@localhost/test');
                // $db = db::factory('mysql://test:test@localhost:3036/test')
                
              $db db::factory('sqlite://localhost/test');
                
              $res $db->query('SELECT * FROM irgendwas');
                while(
              $row $db->fetch($res)) print_r($row);
              }
              catch (
              Exception $e)
              {
                echo 
              '<pre>';
                echo 
              'Ausnahme gefangen: '"\n",  
                        
              $e->getMessage(), "\n",
                        
              $e->getTraceAsString(), "\n";
                echo 
              '</pre>';

              Zuletzt geändert von combie; 01.11.2007, 13:24.
              Wir werden alle sterben

              Kommentar

              Lädt...
              X