Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 30 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
30
Dung lượng
561,27 KB
Nội dung
4 –PHP objektorientiert 240 Die zweite Klasse, die von der Person abgeleitet werden soll, ist die Klasse der Mitarbei- ter. Dabei wird in gleicher Weise wie bei der Kundenklasse vorgegangen. Nur die für einen Mitarbeiter typischen Eigenschaften werden auch in der Mitarbeiterklasse festge- halten. Sie erkennen auch, dass alle Eigenschaften, die Mitarbeiter und Kunden gemeinsam haben, ausschließlich in der Personenklasse gespeichert und verwaltet werden. Auf diese Weise wird doppelter Quellcode verhindert und die Wartbarkeit der Anwendung verbessert. Sowohl der Mitarbeiter als auch der Kunde verfügen über die Eigenschaft $id. Wenn alle konkreten Personen über eine ID verfügen, wieso wird diese ID dann nicht in die Ober- public function __construct($id,$name,$vorname,$strasse,$plz,$ort){ parent::__construct($name,$vorname,$strasse,$plz,$ort); $this->id=$id; } public function getID(){ return $this->id; } } ?> <?php class Mitarbeiter extends Person{ private $id; private $tarifGruppe; private $firmenEintritt; public function __construct($id,$name,$vorname,$strasse,$plz,$ort, $tarifGruppe,$firmenEintritt){ parent::__construct($name,$vorname,$strasse,$plz,$ort); $this->id=$id; $this->tarifGruppe=$tarifGruppe; $this->firmenEintritt=$firmenEintritt; } public function getID(){ return $this->id; } } ?> Listing 4.26: Die abgeleitete konkrete Klasse „Mitarbeiter“ Listing 4.25: Die abgeleitete konkrete Klasse „Kunde“ (Forts.) Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. Realisierung von Klassengeflechten PHP–Endlich objektorientiert 241 klasse ausgelagert? In PHP ist dies durchaus eine Designalternative, da der Datentyp einer Eigenschaft nicht im Vorfeld festgelegt werden muss. Es können jedoch auch hier Probleme auftreten, wenn man in einer Set-Methode die Gültigkeit einer ID prüfen muss. Denn der Identifikator kann bei einem Kunden völlig anders aufgebaut sein als bei einem Mitarbeiter. Ein Lösungsansatz würde für PHP darin bestehen, die Eigenschaft $id zentral für den Kunden protected anstatt private zu definieren. Damit könnten auch Methoden der Unterklasse direkt auf die Eigenschaft zugreifen. Im zweiten Schritt könn- ten dann die Set-Methoden des Kunden und des Mitarbeiters mit den entsprechenden Prüfungen überschrieben werden. Wie man Methoden überschreibt, wird im nächsten Beispiel erläutert. In Listing 4.27 werden zunächst die drei erzeugten Klassen getestet. Es werden ein Kunde und ein Mitarbeiter erzeugt. Weil beide auch Personen sind, besitzen sie die Methode getAnschrift(), die in beiden Fällen aufgerufen wird. Abschließend wird test- weise der PHP-Befehl get_parent_class auf der Referenz des Mitarbeiterobjekts angewen- det. Sie gibt den Namen der Oberklasse des Mitarbeiters, also Person zurück. Die Ausgabe der Testklasse lautet wie erwartet: Frank Dopatka Hauptstrasse 4 51580 Reichshof Ulli Streber Sackgasse 2 12234 Berlin Person Im zweiten Beispiel der Vererbung wird die Tierhierarchie aus dem dritten Kapitel umgesetzt. Dort wurden im objektorientierten Design die Klassen aus Abbildung 4.5 ermittelt. <?php require_once("classloader.inc.php"); ?> <html><body> <?php $a=new Kunde(1,'Frank','Dopatka','Hauptstrasse 4',51580,'Reichshof'); echo $a->getAnschrift(); $b=new Mitarbeiter('E34','Ulli','Streber','Sackgasse 2',12234,'Berlin', 'TvöD13','31.01.2008'); echo $b->getAnschrift(); echo get_parent_class($b); ?> </body></html> Listing 4.27: Testklasse der Vererbung Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. 4 –PHP objektorientiert 242 Die abstrakte Klasse Tier hat eine Eigenschaft name, die als protected deklariert ist. Somit kann der Zugriff für abgeleitete Klassen wie auf eine public-deklarierte Eigenschaft erfol- gen. Zusätzlich dazu ist auch die Methode gibLaut() im Tier laut der Definition im Klassendia- gramm der UML abstrakt definiert. Man möchte also, dass jedes konkrete Tier Laut geben kann. Wie dieser Laut jedoch aussieht, hängt von dem konkreten Tier ab. Abgeleitet von der Tierklasse werden die Klassen Hund und Katze. Sie implementieren das Lautgeben und zusätzlich noch die eigenen Methoden bellen() und miauen(). Jemand, der einen Hund verwaltet, möchte den konkreten Laut unter Umständen direkt abfragen. Zusätzlich ist eine Dogge ein spezieller Hund. Er kann besonders gut beißen und bietet dies als eigene Methode an. Abbildung 4.5: Klassendiagramm der Tierhierarchie Listing 4.28 zeigt die Umsetzung der Tierklasse in PHP 5. Beachten Sie die Syntax der abstrakten Methode gibLaut(). <?php abstract class Tier{ protected $name; Listing 4.28: Die abstrakte Klasse „Tier“ mit abstrakter Methode „gibLaut“ Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. Realisierung von Klassengeflechten PHP–Endlich objektorientiert 243 Im nächsten Schritt wird die Katze modelliert, die ein Tier ist. Im Konstruktor besteht die Möglichkeit, die Eigenschaft name direkt zu setzen. Darauf wird jedoch verzichtet und stattdessen der Konstruktor der Oberklasse aufgerufen. Dort könnten zukünftig noch weitere Initialisierungen vorgenommen werden, die auch für ein Katzenobjekt von Bedeutung wären. Neben der Bereitstellung der Methode miauen() ist die Implementierung der Methode gibLaut() zu nennen. Die Methodendefinition muss genauso lauten wie in der Oberklasse bis auf das fehlende Schlüsselwort abstract. Dadurch, dass diese Methode nun realisiert wurde, können konkrete Objekte der Klasse angelegt werden. Die Implementierung der Hundeklasse erfolgt in Listing 4.30 analog zur Katzenklasse. public function __construct($name){ $this->name=$name; } public function getName(){ return $this->name; } abstract public function gibLaut(); } ?> <?php class Katze extends Tier{ public function __construct($name){ parent::__construct($name); } public function gibLaut(){ return $this->miauen(); } public function miauen(){ return 'miau'; } } ?> Listing 4.29: Die abgeleitete Klasse „Katze“ Listing 4.28: Die abstrakte Klasse „Tier“ mit abstrakter Methode „gibLaut“ (Forts.) Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. 4 –PHP objektorientiert 244 Von der Hundeklasse wird wiederum die Dogge als spezieller Hund abgeleitet. Da der Hund bereits das Lautgeben implementiert, ist dies bei der Dogge nicht zwingend nötig. Der Laut könnte natürlich durch ein Überschreiben der Methode mit identischer Defini- tion public function gibLaut() neu definiert werden. Stattdessen wird die Methode get- Name() bei der Dogge im Vergleich zum Tier neu definiert. Zusätzlich wird die neue Methode beissen() definiert. <?php class Hund extends Tier{ public function __construct($name){ parent::__construct($name); } public function gibLaut(){ return $this->bellen(); } public function bellen(){ return 'wow'; } } ?> Listing 4.30: Die abgeleitete Klasse „Hund“ <?php class Dogge extends Hund{ public function __construct($name){ parent::__construct($name); } public function beissen(){ return 'grrr .'; } public function getName(){ return $this->name.' die Dogge.'; } } ?> Listing 4.31: Die Dogge als spezieller Hund Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. Realisierung von Klassengeflechten PHP–Endlich objektorientiert 245 Der Test der Tierklassen erfolgt in Listing 4.32. Dabei wird ein Datenfeld angelegt, das mit einer Katze und einer Dogge gefüllt wird. Beide geben ihren Namen aus, dann beißt die Dogge einmal zu. Da die Dogge die Methode getName() neu definiert hat, wird die neue Methode ausgeführt. Anschließend soll jedes Tier im Datenfeld einen Laut von sich geben. Dazu wird das Feld in einer Schleife durchlaufen. Dies ist natürlich besonders bei großen Feldern von Inter- esse. Mit instanceof sollte noch eine zusätzliche Typprüfung durchgeführt werden, ob es sich bei den Elementen des Feldes wirklich um Tiere handelt. Zum Abschluss wird versucht, jedes Tier im Datenfeld zum Miauen zu bringen. Bei der Dogge sollte dies problematisch werden. Die Ausgabe ist auch hier erwartungsgemäß. Interessant ist auch die Fehlermeldung, dass eine Dogge nicht miauen kann. Nicki Hasso die Dogge. grrr . miau wow miau Fatal error: Call to undefined method Dogge::miauen() in . <?php require_once("classloader.inc.php"); ?> <html><body> <?php $zoo=Array(); $zoo[0]=new Katze('Nicki'); echo $zoo[0]->getName().'<br>'; $zoo[1]=new Dogge('Hasso'); echo $zoo[1]->getName().'<br>'; echo $zoo[1]->beissen().'<br>'; for ($i=0;$i<2;$i++){ echo $zoo[$i]->gibLaut().'<br>'; } for ($i=0;$i<2;$i++){ echo $zoo[$i]->miauen().'<br>'; } ?> </body></html> Listing 4.32: Testklasse für verschiedene Tiere Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. 4 –PHP objektorientiert 246 4.2.2 Aufbau von Bekanntschaften: Assoziationen Die Vererbung ist eine statische Abhängigkeit von Klassen, die zur Entwicklungszeit festgelegt wird. Die Bekanntschaft von Objekten untereinander entsteht jedoch erst zur Laufzeit. Nachdem ein Objekt ein anderes Objekt kennt, kann es Methoden auf dem bekannten Objekt ausführen. Als Beispiel wird die Beziehung einer Rechnungsposition zu einem Artikel verwendet. Das Klassendiagramm der Abbildung 4.6 gibt dabei die Eigenschaften beider Klassen vor. Aus Sicht des Artikels ist die Bindung sehr lose; ein Artikel kennt keine Rechnungs- positionen. Er kann aber auf vielen Rechnungspositionen enthalten sein. Eine Rechnungsposition kennt stets genau einen Artikel, der in einer gewissen Menge eingekauft werden soll. Diese Abhängigkeit besteht bereits beim Erstellen der Rech- nungsposition. Zusätzlich wird der Einzelpreis des Artikels und ggf. ein Rabatt auf die jeweilige Rechnungsposition festgehalten. Abbildung 4.6: Beziehung zwischen einer Rechnungsposition und einem Artikel Listing 4.33 zeigt die Implementierung einer Rechnungsposition. Der Artikel ist dabei eine Eigenschaft der Rechnungsposition und wird als Referenz im Konstruktor überge- ben. Der Einzelpreis der Rechnungsposition wird aus dem Verkaufspreis des Artikels ermittelt. Außerdem werden dir typischen Get-Methoden implementiert. Der Gesamt- preis ist keine eigene Eigenschaft, sondern wird aus den existierenden Eigenschaften unter Berücksichtigung des optionalen Rabatts auf die Rechnungsposition sowie der Mehrwertsteuer aus dem Artikel berechnet. <?php class Rechnungsposition{ private $artikel; private $menge; private $ep; private $rabatt; // % public function __construct($artikel,$menge,$rabatt){ $this->artikel=$artikel; $this->menge=$menge; $this->ep=$artikel->getVK(); $this->rabatt=$rabatt; } public function getArtikel(){ Listing 4.33: Die Klasse „Rechnungsposition“ Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. Realisierung von Klassengeflechten PHP–Endlich objektorientiert 247 Die in Listing 4.34 implementierte Artikelklasse hat keine Besonderheiten, sie implemen- tiert lediglich die aus dem Klassendiagramm geforderten Eigenschaften und bietet Get- Methoden dazu an. Abbildung 4.7 zeigt nun ein Objektdiagramm des kleinen Testprogramms, das in Listing 4.33 vorgestellt wird. Da das Objektdiagramm ein konkretes Beispiel aus der objektorien- tierten Analyse bildet, aus dem die Klassendiagramme erst abgeleitet werden (Kap. 3), muss dieses Beispiel jetzt nachgebildet werden können. return $this->artikel; } . public function getGesamtpreis(){ return (($this->ep)*($this->menge))*(1-($this->rabatt)/100)* (1+$this->artikel->getMwST()/100); } } ?> <?php class Artikel{ private $id; private $name; private $beschreibung; private $ek; private $vk; private $mwst; public function __construct($id,$name,$beschreibung,$ek,$vk,$mwst){ $this->id=$id; $this->name=$name; $this->beschreibung=$beschreibung; $this->ek=$ek; $this->vk=$vk; $this->mwst=$mwst; } public function getId(){ return $this->id; } . public function getMwSt(){ return $this->mwst; } } ?> Listing 4.34: Die Klasse „Artikel“ Listing 4.33: Die Klasse „Rechnungsposition“ (Forts.) Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. 4 –PHP objektorientiert 248 Abbildung 4.7: Objektdiagramm einer Rechnungsposition mit einem Artikel Zunächst wird der Artikel erstellt und danach die Rechnungsposition. Diese erhält beim Konstruktoraufruf die Referenz auf den Artikel. Interessant ist auch die Möglichkeit, über die Rechnungsposition den Artikel zu ermitteln und dann eine Methode dieses Artikels, in diesem Fall getBeschreibung(), aufzurufen. Dieser Aufruf kann über $pos01- >getArtikel()->getBeschreibung() in einer Zeile erfolgen. Somit lautet die Ausgabe des Testprogramms wie folgt: Name: Butter Beschreibung: gute Butter Menge: 5 Einzelpreis: 0.70 EUR Gesamtpreis: 3.75 EUR 4.2.3 Wechselseitige Bekanntschaften Schwieriger zu realisieren ist die wechselseitige Assoziation zweier Klassen. Als Beispiel wird die Beziehung zwischen Studenten und Praktika realisiert. Da ein Student eine spe- zielle Person ist, kann die implementierte Personenklasse aus Listing 4.24 weiterverwen- det werden. <?php require_once("classloader.inc.php"); ?> <html><body> <?php $a2=new Artikel(2,'Butter','gute Butter',0.50,0.70,7); $pos01=new Rechnungsposition($a2,5,0); echo 'Name: '.$pos01->getArtikel()->getName().'<br>'; echo 'Beschreibung: '.$pos01->getArtikel()->getBeschreibung().'<br>'; echo 'Menge: '.$pos01->getMenge().'<br>'; echo 'Einzelpreis: '.number_format($pos01->getEP(),2).' EUR<br>'; echo 'Gesamtpreis: '.number_format($pos01->getGesamtpreis(),2). ' EUR<br>'; ?> </body></html> Listing 4.35: Test einer Rechnungsposition und eines Artikels Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. Realisierung von Klassengeflechten PHP–Endlich objektorientiert 249 Im Gegensatz zu einer Person besitzt ein Student zusätzlich eine Matrikelnummer und ein Datum der Immatrikulation. Ein Student kann sich an bis zu 5 Praktika gleichzeitig anmelden. Man kann einen Studenten fragen, an welchen Praktika er teilnimmt. Er gibt daraufhin ein Datenfeld seiner Praktikumsobjekte zurück. Nach einer Anmeldung soll der Student sein Praktikum kennen, er muss ja wissen, an welchen Veranstaltungen er teilnimmt, und gleichzeitig muss auch das Praktikum seine Studenten kennen, da ggf. eine Anwesenheitspflicht besteht. Ein Praktikum hat einen Namen und eine Zeitdauer, in dem es stattfindet. Zu einem Praktikum können sich bis zu 20 Studenten anmelden. Eine andere Sichtweise besteht darin, dass sich ein Student an einem Praktikum anmeldet. Beide Klassen verfügen also über eine Methode anmelden. Abbildung 4.8: Wechselseitige Beziehung zwischen Praktika und Studenten Profitipp Sie erkennen hier, dass eine sinnvoll durchdachte abstrakte Klasse auch in verschie- denem Kontext – in Listing 4.24 war der Kontext die Ableitung von Kunden und Mit- arbeitern – weiterverwendet werden und damit langfristig Ressourcen der Imple- mentierung einsparen kann. Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. [...]... Dopatka->Betriebssysteme: bool(true) anmelden PHP- >Dopatka: bool(true) anmelden Grube- >PHP: bool(true) anmelden Netzwerke->Grube: bool(true) Dopatka: Betriebssysteme PHP für Anfänger PHP–Endlich objektorientiert Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark 255 4 –PHP objektorientiert Grube: Betriebssysteme Netzwerke Betriebssysteme: Dopatka Grube PHP: Dopatka Netzwerke: Grube 4.2.4... FALSE; // anmelden $this->studs[$this->anzStuds]=$stud; $this->anzStuds++; // dem Studenten Bescheid sagen Listing 4.37: Die Klasse „Praktikum“ PHP–Endlich objektorientiert Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark 253 4 –PHP objektorientiert if (($stud->anmelden($this))==FALSE){ $this->anzStuds ; $this->studs[$this->anzStuds]=NULL; return FALSE; } return TRUE; }... $this->immatrikuliertSeit; } public function getPraktika(){ return $this->praks; } public function anmelden($prak){ Listing 4.36: Die Klasse „Student“ PHP–Endlich objektorientiert Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark 251 4 –PHP objektorientiert if (($prak instanceof Praktikum)==FALSE) return FALSE; foreach (($this->praks) as $elem => $wert){ if ($wert==$prak) return... addRechnung($rechnung){ $this->rechnungen[$this->anzRechnungen]=$rechnung; $this->anzRechnungen++; } } ?> Listing 4.39: Die erweiterte Kundenklasse PHP–Endlich objektorientiert Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark 257 4 –PHP objektorientiert Stellen Sie sich vor, dass Sie die alte Kundenklasse aus Listing 4.25 bereits vielfältig im Einsatz haben Sie können die existierende... $position[$i][4]=$p->getGesamtpreis(); $i++; } return $position; } public function setBezahlt($bezahlt){ if ($bezahlt==TRUE){ Listing 4.40: Die neue Rechnungsklasse (Forts.) PHP–Endlich objektorientiert Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark 259 4 –PHP objektorientiert $this->bezahlt=TRUE; } else{ $this->bezahlt=FALSE; } } public function addPosition($artikel,$menge,$rabattPos){ $this->positionen[$this->anzPositionen]=new... von HTML-Tabellen und CSS-Formatierungen verschönert werden kann: RECHNUNG Nr 1 vom 08.10.2009: Kunde: Dopatka Rabatt auf die Gesamtrechnung: 5% PHP–Endlich objektorientiert Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark 261 4 –PHP objektorientiert Position 1: Milch, 3 Stück, 0% Rabatt 1.20EUR pro Stück, 3.85EUR gesamt incl 7% MwSt Position 2: Zucker, 1 Stück, 0% Rabatt... oder yKoordinaten besitzen Es kommt also die folgende dritte Bedingung hinzu: Drei Punkte bilden kein Dreieck, wenn Sie auf einer Geraden liegen PHP–Endlich objektorientiert Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark 263 4 –PHP objektorientiert Profitipp Streng genommen müssen Sie im Konstruktor des Dreiecks prüfen, ob das Dreieck überhaupt gebildet werden darf Die... sein < ?php require_once("classloader.inc .php" ); ?> < ?php $p1=new Punkt(0,10); $p2=new Punkt(5,5); $p3=new Punkt(10,5); $d1=new Dreieck($p1,$p2,$p3); echo $d1.''; $p4=new Punkt(1,1); $p5=new Punkt(2,2); $p6=new Punkt(3,3); $d2=new Dreieck($p4,$p5,$p6); echo $d2.''; ?> Listing 4.44: Erstellung von Punkten und Dreiecken PHP–Endlich objektorientiert Please purchase... Referenz auf die geöffnete Verbindung wird in der Eigenschaft $conn festgehalten Je nach Erfolg gibt die öffnen-Methode TRUE oder FALSE zurück PHP–Endlich objektorientiert Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark 267 4 –PHP objektorientiert Die schließen-Methode aus dem Interface ist durch den Befehl mysql_close() leicht zu implementieren Die Prüfung der Eingabeparameter... Funktion in beiden Fällen sichergestellt < ?php require_once("classloader.inc .php" ); ?> < ?php $s1=new Student(3423433,'Dopatka','Frank','Hauptstrasse 4',51580, 'Reichshof','01.10.2002'); $s2=new Student(8977678,'Grube','Clair','Kanzlergasse 1',16334, 'Berlin','01.04.2001'); $p1=new Praktikum('Betriebssysteme','08:00','10:00'); $p2=new Praktikum( 'PHP für Anfänger','10:00','12:00'); $p3=new . watermark. Realisierung von Klassengeflechten PHP – Endlich objektorientiert 241 klasse ausgelagert? In PHP ist dies durchaus eine Designalternative, da. aus Abbildung 4.5 ermittelt. < ?php require_once("classloader.inc .php& quot;); ?> <html><body> < ?php $a=new Kunde(1,'Frank','Dopatka','Hauptstrasse