Tag 7 Repetitorium Informatik (Java) Dozent: Patrick Kreutzer Lehrstuhl für Informatik 2 (Programmiersysteme) Friedrich-Alexander-Universität Erlangen-Nürnberg Wintersemester 2017/2018
Informatik-Repetitorium Tag 7 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 2 / 36
Übersicht Klassen und Objekte Grundbegriffe Definition von Klassen Instanzmethoden/-variablen vs. Klassenmethoden/-variablen Instanziierung von Klassen Erzeugung von Objekten Konstruktoren Übersetzen/Ausführen mit mehreren Klassen Informatik-Repetitorium Tag 7 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 3 / 36
Klassen und Objekte
Motivation (I) bisher: Verwendung von vordefinierten (primitiven) Datentypen int, double, boolean,... eine Variable eines solchen Typs speichert immer genau ein Datum Arrays, um mehrere Werte desselben Typs zu speichern aber: häufig: Daten unterschiedlichen Typs, die konzeptuell zusammengehören zusätzlich Methoden, die auf bzw. mit diesen Daten arbeiten jetzt: Definition und Verwendung von eigenen, zusammengesetzten Datentypen Einstieg in die Objektorientierte Programmierung (OOP) Informatik-Repetitorium Tag 7 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 5 / 36
Motivation (II) Bisher... // zwei Konten... int kontonr1 = 12345678; String eigentuemer1 = " Musterfrau "; double kontostand1 = 1303.12; int kontonr2 = 87654321; String eigentuemer2 = " Mustermann "; double kontostand2 = 4711.08; //... und eine "Ü berweisung " System. out. println ("Ü berweisung von " + kontonr1 + " nach " + kontonr2 ); kontostand1 = kontostand1-50; kontostand2 = kontostand2 + 50; Nicht schön... Obwohl Kontonummer, Eigentümer und Kontostand jeweils zusammengehören, sind sie in unabhängigen Variablen gespeichert. Pro neues Konto müssten drei neue Variablen angelegt werden. Die Implementierung der Überweisung ist von den Daten getrennt. Informatik-Repetitorium Tag 7 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 6 / 36
Motivation (III) Ziel für unser Beispiel: Definition und Verwendung eines neuen Datentyps Konto speichert die Daten Kontonummer, Eigentümer und Kontostand bietet eine Methode, um eine Überweisung zu tätigen Objektorientierte Programmierung (OOP): Daten und zugehörige Operationen, die auf diesen Daten arbeiten, zu einer konzeptuellen und organisatorischen Einheit zusammenfassen ( Klasse) was zusammengehört, wird zusammengefasst was nicht zusammengehört, wird voneinander getrennt erlaubt Modularisierung und Wiederverwendung ein Programm besteht i.a. aus vielen verschiedenen Klassen diese Klassen verwenden sich gegenseitig Informatik-Repetitorium Tag 7 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 7 / 36
Grundbegriffe: Klassen und Objekte Klasse OOP-Konzept zur Definition neuer, zusammengesetzter Datentypen die Klassendefinition legt fest: Attribute: Variablen für zu speichernde Daten Methoden: zur Verfügung stehende Operationen auf den Daten stellt eine Art Schablone oder Bauplan dar Objekt konkretes Exemplar einer Klasse eine Ausprägung wird gemäß der Schablone erzeugt und kann entsprechend verwendet werden i.a. werden mehrere Objekte derselben Klasse erzeugt und verwendet Informatik-Repetitorium Tag 7 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 8 / 36
Klassen und Objekte in unserem Beispiel Klasse Konto Attribute: kontonummer, eigentuemer, kontostand Methoden: ueberweisen, kontostandausgeben Objekte der Klasse Konto kontonummer: 12345678 eigentuemer: Musterfrau kontostand: 1303.91 kontonummer: 87654321 eigentuemer: Mustermann kontostand: 4711.08... Merke Es wird einmalig bei der Klassendefinition festgelegt, welche Attribute (und Methoden) ein Konto hat, aber jedes Objekt hat eigene Kopien der Attribute mit eigenen Werten. Informatik-Repetitorium Tag 7 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 9 / 36
Klassen und Objekte in einem anderen Beispiel Klasse Mitarbeiter Attribute: name, gehalt, abteilung Methoden: befoerdern, entlassen Objekte der Klasse Mitarbeiter name: Musterfrau gehalt: 3100.00 abteilung: Abteilung A name: Mustermann gehalt: 2800.00 abteilung: Abteilung B... Informatik-Repetitorium Tag 7 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 10 / 36
Definition von Klassen Syntax: Klassendefinition (vereinfacht) Modifizierer class Klassenname { Definitionen Hinweise Modifizierer zunächst immer nur public Datei muss genauso heißen wie die Klasse Klassenname bestehend aus Buchstaben, Zahlen und (bestimmten) Sonderzeichen Konventionen: ausschließlich Buchstaben, beginnend mit Großbuchstaben Definitionen Deklaration von Attributen und Methoden Reihenfolge egal, per Konvention üblicherweise zuerst Attribute Informatik-Repetitorium Tag 7 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 11 / 36
Attribute bisher: nur lokale Variablen Deklaration innerhalb von Methoden (bzw. darin verschachtelten Blöcken) Verwendung nur innerhalb dieser Methode (bzw. dieses Blocks) möglich jetzt: Attribute ( globale Variablen ) Deklaration direkt innerhalb einer Klasse Syntax zur Deklaration und Initialisierung wie bei lokalen Variablen Zugriff aus allen Methoden (und ggf. von außerhalb, s.u.) möglich Beispiel public class Konto { int kontonummer ; String eigentuemer ; double kontostand ; Informatik-Repetitorium Tag 7 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 12 / 36
Instanzmethoden/-variablen vs. Klassenmethoden/-variablen Jetzt wird es ein ganzes Stück komplizierter. Bei Unklarheiten Fragen stellen! bekannt: Unterscheidung: Objekt Klasse jetzt: Unterscheidung: Instanzmethode/-variable Klassenmethode/-variable grob (Details kommen gleich!): eine Instanzmethode/-variable gehört zu einem einzelnen konkreten Objekt Zugriff auf eine solche Methode/Variable nur über ein Objekt der Klasse eine Klassenmethode/-variable gehört zu der gesamten Klasse Zugriff auf eine solche Methode/Variable ohne konkretes Objekt möglich Informatik-Repetitorium Tag 7 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 13 / 36
Instanzvariablen eine Instanzvariable gehört zu einem einzelnen konkreten Objekt eine Instanzvariable wird einmalig innerhalb der Klasse deklariert aber: jedes Objekt hat eine eigene Kopie jeder Instanzvariable jedes Objekt kann eigenen Wert für seine Instanzvariable haben Deklaration einer Instanzvariable ohne weiteres Schlüsselwort (im Gegensatz zu Klassenvariablen, siehe unten) Beispiel: Konto Jedes Konto soll jeweils eigene Kontonummer, Eigentümer und Kontostand haben. Deshalb deklarieren wir die Attribute als Instanzvariablen. Beispiel: Konto public class Konto { int kontonummer ; String eigentuemer ; double kontostand ; Informatik-Repetitorium Tag 7 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 14 / 36
Klassenvariablen eine Klassenvariable gehört zu der gesamten Klasse alle Objekte der Klasse teilen sich eine Klassenvariable alle Objekte der Klasse lesen und schreiben die identische Variable nützlich für Variablen, die konzeptuell zwar zu einer Klasse gehören, die aber für alle Objekte der Klasse denselben Wert haben sollen Deklaration einer Klassenvariable mit zusätzlichem Schlüsselwort static Beispiel: Konto Die Konto-Objekte sollen aufsteigende Kontonummern erhalten. Um herausfinden zu können, wie viele Konten es gibt (und was demnach die nächste Kontonummer ist), verwenden wir eine Klassenvariable. Beispiel: Konto public class Konto { static int kontenanzahl ; int kontonummer ; String eigentuemer ; double kontostand ; Informatik-Repetitorium Tag 7 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 15 / 36
Klassen- und Instanzvariablen im Beispiel Beispiel: Konto public class Konto { static int kontenanzahl ; int kontonummer ; String eigentuemer ; double kontostand ; Variablen im Speicher kontenanzahl kontonummer eigentuemer kontostand kontonummer eigentuemer kontostand kontonummer eigentuemer kontostand Informatik-Repetitorium Tag 7 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 16 / 36
Zugriff auf Instanz- und Klassenvariablen (I) Syntax: Zugriff auf Instanzvariablen Objektvariable. Variablenname Syntax: Zugriff auf Klassenvariablen Klassenname. Variablenname Hinweise für den Zugriff auf eine Instanzvariable braucht man eine Objektvariable gibt an, welche Kopie der Instanzvariable gelesen bzw. geschrieben werden soll für den Zugriff auf eine Klassenvariable reicht der Klassenname Informatik-Repetitorium Tag 7 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 17 / 36
Zugriff auf Instanz- und Klassenvariablen (II) Beispiel: Konto public class Konto { static int kontenanzahl ; int kontonummer ; String eigentuemer ; double kontostand ; Beispiel: Bank public class Bank { public static void main ( String [] args ) { Konto konto1 ; // hier fehlt noch die Erzeugung des // Kontos ( siehe unten ) Konto. kontenanzahl += 1; konto1. kontonummer = Konto. kontenanzahl ; Aus didaktischen Gründen... Normalerweise würde man das Zählen der Konten und die Vergabe der Kontonummer innerhalb der Klasse Konto implementieren (siehe unten). Informatik-Repetitorium Tag 7 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 18 / 36
Instanzmethoden eine Instanzmethode arbeitet auf einem konkreten Objekt kann auf die Instanzvariablen dieses Objekts zugreifen man sagt: eine Instanzmethode wird auf einem Objekt aufgerufen wie beim Zugriff auf Instanzvariablen wird eine Objektvariable benötigt Deklaration einer Instanzmethode ohne Schlüsselwort static Beispiel: Konto Die Klasse Konto soll um eine Methode erweitert werden, die den Kontostand eines Kontos ausgibt. Da diese Methode Zugriff auf eine Instanzvariable eines konkreten Objekts braucht, verwenden wir eine Instanzmethode. Beispiel: Konto public class Konto { double kontostand ; //... public void kontostandausgeben () { System. out. println ( " Kontostand : " + kontostand ); Informatik-Repetitorium Tag 7 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 19 / 36
Selbstreferenz: this (I) jede Instanzmethode kennt das Objekt, auf dem sie aufgerufen wurde zugreifbar über die implizit definierte Variable this alternativer Zugriff auf die eigenen Instanzvariablen (und -methoden) Beispiel ohne this public class Konto { double kontostand ; //... public void kontostandausgeben () { System.out. println ( " Kontostand : " + kontostand ); Beispiel mit this public class Konto { double kontostand ; //... public void kontostandausgeben () { System. out. println ( "... " + this. kontostand ); Empfehlung Beim Zugriff auf die eigenen Instanzvariablen immer ein this voranstellen. Informatik-Repetitorium Tag 7 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 20 / 36
Selbstreferenz: this (II) this notwendig bei Namenskonflikt zwischen Instanzvariable/lokaler Variable this.variablenname Instanzvariable Variablenname lokale Variable Beispiel: Namenskonflikt zwischen Instanzvariable/lokaler Variable public class Konto { double kontostand ; //... public void setzekontostand ( double kontostand ) { this. kontostand = kontostand ; // FALSCH w ä re: kontostand = kontostand ; Informatik-Repetitorium Tag 7 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 21 / 36
Klassenmethoden eine Klassenmethode arbeitet auf der gesamten Klasse kann ohne konkretes Objekt auf der Klasse aufgerufen werden kann nicht auf Instanzvariablen zugreifen, nur auf Klassenvariablen nützlich für Methoden, die konzeptuell zu einer Klasse gehören, aber kein konkretes Objekt der Klasse benötigen Deklaration einer Klassenmethode mit zusätzlichem Schlüsselwort static Beispiel: Konto Die Klasse Konto soll um eine Methode erweitert werden, die die Anzahl der Konten ausgibt. Da diese Methode kein konkretes Objekt und nur Zugriff auf Klassenvariablen braucht, verwenden wir in diesem Fall eine Klassenmethode. Beispiel: Konto public class Konto { static int kontenanzahl ; //... public static void anzahlausgeben () { System.out. println ( "# Konten : " + kontenanzahl ); Informatik-Repetitorium Tag 7 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 22 / 36
Zugriff auf Instanz- und Klassenmethoden (I) Syntax: Zugriff auf Instanzmethoden Objektvariable. Methodenname ( Argument1, Argument2,...) Syntax: Zugriff auf Klassenmethoden Klassenname. Methodenname ( Argument1, Argument2,...) Hinweise für den Zugriff auf eine Instanzmethode braucht man eine Objektvariable bestimmt, auf welchem Objekt die Instanzmethode aufgerufen wird legt die this-variable innerhalb der Instanzmethode fest bei einem Aufruf auf demselben Objekt (this) kann die Objektvariable entfallen für den Zugriff auf eine Klassenmethode reicht der Klassenname bei einem Aufruf innerhalb derselben Klasse kann der Klassenname entfallen Informatik-Repetitorium Tag 7 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 23 / 36
Zugriff auf Instanz- und Klassenmethoden (II) Beispiel: Konto public class Konto { static int kontenanzahl ; int kontonummer ; String eigentuemer ; double kontostand ; public void kontostandausgeben () { System.out. println ( " Kontostand : " + this. kontostand ); Beispiel: Bank public class Bank { public static void macheausgaben () { Konto konto1 ; // hier fehlt noch die Erzeugung // des Kontos ( siehe unten ) Konto. anzahlausgeben (); konto1. kontostandausgeben (); public static void anzahlausgeben () { System.out. println ( "# Konten : " + kontenanzahl ); public static void main ( String [] args ){ // Klassenmethode in gleicher Klasse // -> Klassenname kann entfallen macheausgaben (); Informatik-Repetitorium Tag 7 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 24 / 36
Instanz- oder Klassenmethode? (I) Methode ueberweisung() Sollte die Methode ueberweisung() eine Instanz- oder eine Klassenmethode sein? Überlegungen arbeitet auf konkreten Objekten und deren Instanzvariablen ueberweisung() als Instanzmethode? arbeitet auf zwei konkreten Objekten Welches der beiden Objekte ist this? Bedeutet k1.ueberweisung(k2, 10.00) eine Überweisung von oder nach k1? ueberweisung() als Klassenmethode mit zwei Konto-Parametern? Geht beides! Letztendlich ist es eine Entwurfsentscheidung Informatik-Repetitorium Tag 7 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 25 / 36
Instanz- oder Klassenmethode? (II) Als Instanzmethode public class Konto { double kontostand ; //... Als Klassenmethode public class Konto { double kontostand ; //... // Name deutet Verwendung an! public void ueberweisungnach ( Konto empfaenger, double betrag ) { this. kontostand -= betrag ; empfaenger. kontostand += betrag ; public static void ueberweisung ( Konto empfaenger, Konto sender, double betrag ) { sender. kontostand -= betrag ; empfaenger. kontostand += betrag ; Informatik-Repetitorium Tag 7 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 26 / 36
Instanziierung von Klassen
Wiederholung: Erzeugung von Arrays bekannt: ein Array muss vor der Verwendung erst erzeugt werden Instanziierung mit dem Schlüsselwort new unter Angabe der Größe Beispiel: Array-Instanziierung int [] zahlen = new int [13]; die Array-Variable (zahlen) speichert eine Referenz auf das neue Array Referenz Information, wo das Objekt im Speicher liegt Details zu Referenzen gibt es morgen Informatik-Repetitorium Tag 7 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 28 / 36
Erzeugung von Objekten auch Klassen müssen instanziiert werden, um konkrete Objekte zu erzeugen erfolgt wie bei Arrays mit Hilfe des Schlüsselworts new Angabe des Klassennamens und ggf. Übergabe von Argumenten (s.u.) Instanziierung kann (wie bei Arrays) bei der Deklaration erfolgen Beispiel: Konto Konto konto1 ; konto1 = new Konto (); Konto konto2 = new Konto (); Achtung! Greift man auf eine nicht-initialisierte Objektvariable zu, schlägt die Übersetzung fehl oder das Programm bricht bei der Ausführung mit einer sog. NullPointerException ab. Informatik-Repetitorium Tag 7 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 29 / 36
Verwendung von Objektvariablen Objektvariablen können wie Variablen mit primitivem Typ verwendet werden können beispielsweise als Argument an Methoden übergeben werden Beispiel: Konto public class Konto { int kontonummer ; double kontostand ; //... Beispiel: Bank public class Bank { public static void main ( String [] args ) { Konto konto1 = new Konto (); //... ausgabe ( konto1 ); public static void ausgabe ( Konto konto ) { System.out. println ( konto. kontonummer + ": " + konto. kontostand ); Informatik-Repetitorium Tag 7 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 30 / 36
Konstruktoren Konstruktor: spezielle Methode, die bei der Instanziierung aufgerufen wird kann Parameter haben, denen beim Aufruf Werte übergeben werden hat keinen Rückgabetyp (auch nicht void) Konstruktorname und Klassenname müssen identisch sein aber: mehrere Konstruktoren mit unterschiedlichen Parametern möglich Konstruktoren dienen meist der Initialisierung einzelner oder aller Attribute Erzeugung eines konkreten Objektes mit gewünschten Attributwerten falls kein eigener Konstruktor definiert wird: Standardkonstruktor ohne Parameter und ohne weitere Funktionalität ansonsten: Standardkonstruktor entfällt und kann nicht benutzt werden Informatik-Repetitorium Tag 7 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 31 / 36
Konstruktoren: Beispiel (I) Ziel Die Klasse Konto soll einen Konstruktor erhalten, mit dem der Eigentümer und der initiale Kontostand eines Konto-Objekts gesetzt werden können. Das Konto soll automatisch die nächste verfügbare Kontonummer erhalten. Überlegungen Eigentümer und Kontostand sollen dem Konstruktor als Argumente übergeben werden die Klassenvariable kontenanzahl (s.o.) soll die Anzahl an Konten mitzählen die Variable gibt die nächste Kontonummer an die Variable muss im Konstruktor inkrementiert werden Informatik-Repetitorium Tag 7 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 32 / 36
Konstruktoren: Beispiel (II) Beispiel: Konto public class Konto { static int kontenanzahl ; int kontonummer ; String eigentuemer ; double kontostand ; Beispiel: Bank public class Bank { public static void main ( String [] args ) { Konto konto1 = new Konto (" Musterfrau ", 1303.12); public Konto ( String eigentuemer, double kontostand ) { this. eigentuemer = eigentuemer ; this. kontostand = kontostand ; kontenanzahl += 1; this. kontonummer = kontenanzahl ; //... Nicht mehr möglich! public class Bank { public static void main ( String [] args ) { Konto konto1 = new Konto (); Informatik-Repetitorium Tag 7 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 33 / 36
Übersetzen/Ausführen mit mehreren Klassen
Übersetzen und Ausführen mit mehreren Klassen Programme bestehen i.a. aus vielen sich gegenseitig verwendenden Klassen Beispiel: die Klassen Bank und Konto bilden zusammen ein Programm beim Übersetzen müssen alle Klassen des Programms übersetzt werden entweder einzeln und hintereinander oder gleichzeitig Tipp: bei Änderung einer Klasse immer alle Klassen erneut übersetzen Beispiel: Übersetzen von Bank und Konto benutzer@faui06a: /ordner$ javac Bank.java Konto.java für die Ausführung muss die Klasse mit der main-methode angegeben werden Beispiel: Ausführen des Bank-Programms benutzer@faui06a: /ordner$ java Bank Informatik-Repetitorium Tag 7 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 35 / 36
Fragen? Fragen! (hilft auch den anderen)