Vorlesung und Übung Universität Paderborn Wintersemester 2016/2017 Dr. Peter Pfahler Objektorientierung: Klassen und Objekte EWS, WS 2016/17, Pfahler L-1 Objektorientierung behandelt in "Einführung in die Informatik für Geisteswissenschaftler" im letzten Semester am Beispiel JavaScript. Object-oriented programming (OOP) opens the door to cleaner designs, easier maintenance, and greater code reusability. Tatroe, Lerdorf, McIntyre: Programming PHP, O'Reilly Verlag Die Grundidee ist es, die Daten und die Programmteile, die auf den Daten arbeiten als zusammenhängende, untrennbare Einheit zu betrachten. Objektorientierte Sprachen stellen Konstrukte zur Verfügung um diesen Zusammenhang auszudrücken. EWS, WS 2016/17, Pfahler L-2 Klassen und Objekte Eine Klassendefinition beschreibt Daten und Funktionen die auf diesen Daten arbeiten. Die Daten heißen Eigenschaften (properties), die Funktionen heißen Methoden (methods). Zugriff auf Eigenschaften und Methoden mit der -> Notation Ein Objekt ist ein Wert, der zur Laufzeit gemäß der Klassendefinition erzeugt wird. Es enthält die Objekteigenschaften und wird mit den Objektmethoden bearbeitet. class Person { private $name; public $birthday; function get_name ( ) { return $this->name; } function set_name ($new_name) { $this->name = $new_name; } function age() { return ... } } $student = new Person; $student -> set_name("Fred"); print $student->get_name(); $teacher = new Person; $teacher -> set_name("Lämpel"); EWS, WS 2016/17, Pfahler L-3 Objekte erzeugen und verwenden Objekte werden mit dem Operator new gefolgt von dem Klassennamen erzeugt. Die Klasse muss existieren. $student = new Person; Klassen mit parametrisierten Konstruktoren erlauben die Angabe von Parametern bei der Konstruktion. $student = new Person("Helen"); Variablen beinhalten Referenzen auf Objekte. $klausurtn = $student; Zugriff auf Eigenschaften und Methoden mit der -> Notation. print $student->get_name(); print $klausurtn->birthday; Objekte können auch in Arrays gespeichert werden. $teilnehmer[$i] = $klausurtn; EWS, WS 2016/17, Pfahler L-4 Klassen definieren Syntax: class classname [ extends baseclass ] { (visib $property [ = value ]; | visib function method (args) { // code })* } visib ::= 'private'| 'public' | 'protected'| Die Variable this enthält eine Referenz auf das Objekt, für das eine Methode aufgerufen wurde. class Person { private $name; public $birthday = "01.01.1970"; function get_name () { return $this->name; } function set_name ($new_name) { $this->name = $new_name; } function age(); { return ... } } Wie andere Funktionen können Methoden Ergebnisse liefern oder nicht. Initialwerte für Eigenschaften müssen konstant sein. Die Arten der Sichtbarkeit werden auf Folie L-7 behandelt. EWS, WS 2016/17, Pfahler L-5 Erben von anderen Klassen class Person { private $name; private $address; private $age; function print_to_file($f) { // print name, address, age: ... } } Eine Klasse kann Eigenschaften und Methoden von einer anderen Klasse ("Basisklasse") erben. So lassen sich spezialisierte Versionen existierender Klassen erzeugen. Gleich benannte Eigenschaften oder Methoden in der erbenden Klasse überschreiben diejenigen in der Basisklasse. Um dennoch auf Komponenten der Basisklasse zuzugreifen, verwendet man die parent:: - Notation class Employee extends Person { private $position; private $salary; function print_to_file($f) { // print standard data: parent::print_to_file($f); // print position, salary: ... } } EWS, WS 2016/17, Pfahler L-6 Spezifikation der Sichtbarkeit Eigenschaften und Methoden einer Klasse können in ihrer Sichtbarkeit eingeschränkt werden: ● public (das ist der Standard-Wert) ● protected ● private public-Komponenten können überall im Programm benutzt werden. protected-Komponenten können in der eigenen und in erbenden Klassen benutzt werden. class GrandPa { private $name = 'Mark Henry'; } class Daddy extends GrandPa { public function printGrandPa() { print $this->name; } } $daddy = new Daddy; // unzulässig $daddy->printGrandPa(); $grandpa = new GrandPa; // unzulässig print $grandpa->name; private-Komponenten können nur in der eigenen Klassen benutzt werden. Ziel Kapselung: Verhindern von „unstrukturiertem“ Zugriff Empfehlung: Private Eigenschaften, öffentliche Methoden EWS, WS 2016/17, Pfahler Konstruktoren Konstruktoren sind spezielle Methoden, die bei der Objekterzeugung aufgerufen werden. Sie dienen der Initialisierung der Objekte und verarbeiten die Parameter der new-Aufrufe. Bei der Konstruktion von Objekten von Unterklassen müssen Oberklassenkonstruktoren explizit aufgerufen werden: parent::__construct(...); (5, 3)(4, 2) L-7 <?php class Point { private $x; private $y; function __construct($x, $y) { $this->x = $x; $this->y = $y; } function move($dx, $dy) { $this->x = $this->x + $dx; $this->y = $this->y + $dy; } function print_point() { print "($this->x, $this->y)"; } } $p1 = new Point(5, 3); $p2 = new Point(1, -1); $p2->move(3, 3); $p1->print_point(); $p2->print_point(); ?> EWS, WS 2016/17, Pfahler L-8 Überschreiben von Methoden in Unterklassen class ColoredPoint extends Point { private $color; function __construct($x, $y, $c) { parent::__construct($x, $y); $this->color = $c; } function print_point() { parent::print_point(); print "-$this->color"; } } $punkte = array(new Point(1,1), new Point(2,1), new ColoredPoint(2,4,'red'), new Point(2,0), new ColoredPoint(4,1,'blue')); $punkte[4]->move(3,3); foreach ($punkte as $p) { $p->print_point(); echo "\n"; } Dynamische Methodenbindung: Zur Laufzeit wird die auszuführende Methode anhand des Objekttyps bestimmt. (1, (2, (2, (2, (7, 1) 1) 4)-red 0) 4)-blue EWS, WS 2016/17, Pfahler L-9 Beispiel: Die Klasse "Preis" Definieren Sie eine Klasse Preis. Preis-Objekte sollen die privaten Eigenschaften euro und cent haben und die folgenden öffentlichen Methoden: get_cent() ● get_euro() ● __construct() ● print_preis() ● add($p) ● liefert den Cent-Anteil des Preises liefert den Euro-Anteil des Preises Konstruktor mit 2 Parametern Ausgabe-Methode addiert den Preis $p dazu Erproben Sie Ihre Klasse in einer kleinen Anwendung. EWS, WS 2016/17, Pfahler L-10 Lösungsvorschlag: Klasse "Preis" Beispiel-Anwendung $p1 = new Preis(5,28); $p2 = new Preis(1,99); $p1->add($p2); $p1->print_preis(); class Preis { private $euro; private $cent; function __construct($e, $c) { $this->euro = $e; $this->cent = $c; } public function get_cent() { return $this->cent; } public function get_euro() { return $this->euro; } public function print_preis() { echo "$this->euro,$this->cent"; } public function add($p) { $this->euro += $p->euro; $this->cent += $p->cent; if ($this->cent >= 100) { $this->cent -= 100; $this->euro++; } } } EWS, WS 2016/17, Pfahler L-11