Informatik 2 – Teil 1 Objektorientiertes Programmieren und Grundlagen von Java Übersicht 1.1 Warum objektorientierte Programmierung (OOP) 1.15 Kindklassen – Überschreiben von Methoden 1.2 OOP-Grundlagen 1.16 Die Methode main(), Klasseneigenschaften 1.3 Die Programmiersprache Java und - methoden 1.4 Die Plattformunabhängigkeit von Java 1.17 Die Standard-Ausgabe 1.5 Vergleich von Java und C 1.18 Beispiel eines Java-Programms I 1.6 Primitive Datentypen 1.19 Beispiel eines Java-Programms II 1.7 Syntax von Klassen 1.20 Logikoperatoren und der Typ boolean 1.8 Methoden 1.21 Pseudokonstanten, Schlüsselwort final 1.9 Erzeugen von Objekten 1.22 Packages verwenden 1.10 Zugriff auf Objekteigenschaften 1.23 Packages erstellen 1.24 Bemerkungen zur Wortwahl 1.11 Der Konstruktor 1.12 Kapselung 1.13 Kapselung – Beispiel-Schema 1.14 abgeleitete Klassen (Kindklassen), Vererbung Prof. Martin Trauth Folie 1 / 25 Informatik 2 – Teil 1 Objektorientiertes Programmieren und Grundlagen von Java 1.1 Warum objektorientierte Programmierung (OOP)? Im täglichen Leben gehen nur die wenigstens Menschen mit Elementen datenverarbeitender Systeme, wie Variablen oder Funktionen um, die ein Merkmal so genannter imperativer Programmiersprachen (wie C) sind. Statt dessen haben wir es mit „Dingen“ zu tun – man kann auch Objekte dazu sagen. Das können natürliche Dinge sein (z.B. Berge, Tiere), vom Menschen geschaffene (z.B. Maschinen, Gebäude) oder abstrakte Objekte, z.B. ein Bankkonto oder ein „Fenster“ auf dem Bildschirm. OOP soll den datentechnischen Umgang mit diesen „Dingen“ vereinfachen. Ein Ding hat Eigenschaften und Methoden. Nehmen wir einen Elefanten... Der Elefant hat beispielsweise die Eigenschaft Gewicht. Auch sein Standort ist eine seiner Eigenschaften. Oder die Anzahl seiner Beine (normalerweise 4, aber er könnte ja auch ein Invalide sein). Mit seinen Methoden kann er seine Eigenschaften verändern. Mit der Methode „Fressen“ nimmt er an Gewicht zu. Mit „Trinken“ auch. Er hat auch Methoden, die das Gewicht reduzieren, aber das lassen wir hier mal weg. Mit der Methode „Gehen“ verändert er seinen Standort. Prof. Martin Trauth Folie 2 / 25 Informatik 2 – Teil 1 Objektorientiertes Programmieren und Grundlagen von Java 1.2 OOP - Grundlagen Auch bei der OOP verwendet man Objekteigenschaften und Objektmethoden. Sehr wichtig ist außerdem die „Bauanleitung“ die jedes Objekt haben muss. Die meisten objektorientierten Programmiersprachen verwenden dafür den Begriff „Klasse“. Am Beispiel des Elefanten wäre die Klasse eine „Bauanleitung“ für Elefanten. Die Klasse definiert welche Eigenschaften und Methoden alle Objekte haben, die zu dieser Klasse gehören. Im Falle von Elefanten definiert die Klasse also, dass ein Elefant eine Methode „Fressen“ hat und dass er die Eigenschaft „Gewicht“ besitzt. Wenn nun ein Objekt der Klasse „Elefant“ erzeugt wird, dann haben wir die Repräsentation eines individuellen Elefanten, mit individuellem Gewicht und einer individuellen Methode „Fressen“ (sie ist individuell, weil sie nur das Gewicht des Elefanten erhöht zu dem sie gehört). Es kann also beliebig viele Elefanten geben, aber sie folgen alle einem gemeinsamen Bauplan. Das gleiche gilt für Bankkonten: wenn man einmal eine Klasse definiert hat, die alle wesentlichen Eigenschaften und Methoden umfasst, die man zum Umgang mit einem Bankkonto benötigt, dann kann man sie verwenden um beliebig viele Bankkonten (als Objekte) zu erzeugen. Das Schöne ist: diese Klasse kann jede/r in einem Bankprogramm einsetzen und braucht sich nicht darum zu kümmern, wie sie im Detail programmiert ist (zur Definition einer Klasse mit Hilfe einer Programmiersprache muss man natürlich programmieren). Es genügt wenn man die Eigenschaften kennt (z.B. wäre der aktuelle Kontenstand eine Eigenschaft, eine andere ist der Zinssatz für Guthaben) und die verfügbaren Methoden. Ein Beispiel für eine Methode: Auszahlung. Vermindert die Eigenschaft Kontenstand um einen eingegebenen Betrag, eventuell wird auch noch der Kreditrahmen gecheckt und festgestellt, ob die Auszahlung überhaupt erfolgen darf. Prof. Martin Trauth Folie 3 / 25 Informatik 2 – Teil 1 Objektorientiertes Programmieren und Grundlagen von Java 1.3 Die Programmiersprache Java Java, eine von der Firma SUN maßgebend entwickelte und vertriebene Programmiersprache, ist erst seit 1996 auf dem Markt, also noch vergleichsweise „jung“. Ihr großer Markterfolg beruht sicher auf der Tatsache dass das Java Entwicklungssystem (JDK = Java Development Kit) kostenfrei vertrieben wurde, aber auch auf einer Reihe von Vorzügen dieser Programmiersprache: Weitgehende Unabhängigkeit von Hardwareplatform und Betriebssystem. Sehr konsequente Umsetzung des objektorientierten Programmierkonzepts, dennoch relativ einfach strukturierte Sprache Schutzmechanismen gegen Programmierfehler („sicherer“ als C) Viele Programmkomponenten haben die gleiche Syntax wie die bekannte Programmiersprache C Gut geeignet für Web-Anwendungen, da von Beginn an dafür entwickelt Weitere OOP-Programmiersprachen: C++, C#, Visual Basic, Smalltalk, u.v.m. Fast alle neueren Programmiersprachen (auch grafische Programmierung) basieren auf OOP. Prof. Martin Trauth Folie 4 / 25 Informatik 2 – Teil 1 Objektorientiertes Programmieren und Grundlagen von Java 1.4 Die Plattformunabhängigkeit von Java Übliche Compiler-Sprachen, wie C, übersetzen den Quelltext in Maschinencode. Dieser Maschinencode ist natürlich nur auf einer bestimmten CPU lauffähig, d.h. er muss eigens dafür kompiliert werden. Außerdem sind die Gegebenheiten des Betriebssystems zu beachten, unter dem das Programm laufen soll. Java arbeitet mit einer so genannten „Virtual Machine“ (VM). Das ist ein Programm, das eine CPU und (weitgehend) ein Betriebssystem simuliert. Natürlich ist die VM für ein bestimmtes Betriebssystem und eine bestimmte CPU compiliert. Aber wenn man sie einmal hat, dann kann man damit alle Java-Programme laufen lassen. Java-VMs werden von SUN für alle gängigen Betriebssysteme kostenfrei zu Verfügung gestellt. In vielen Fällen werden sie von Java-Anwendungen automatisch aus dem Internet heruntergeladen. Der Ablauf einer Java-Programmerstellung: Editor erstellt Programmtext (Endung .java) Compiler erzeugt ByteCode (Endung .class) Java-VM interpretiert Byte-Code (Ablauf auf CPU) Ein Linker wird für Java nicht benötigt. Prof. Martin Trauth Folie 5 / 25 Informatik 2 – Teil 1 Objektorientiertes Programmieren und Grundlagen von Java 1.5 Vergleich von Java und C Identisch bzw sehr ähnlich sind: Variablendeklaration (aber einige Datentypen sind anders) Zuweisungen Kontrollanweisungen wie if...else, for-, while- und do while-Schleifen (sowie break- und continue-Anweisung) Funktionsaufrufe (wobei man in Java von Methoden spricht) Kommentarzeichen (// oder /* */) Einfache mathematische Operatoren (+, - , *, /, %) Verschiedenheiten: Typische OOP-Strukturen, z.B. Klassen (diese ähneln aber z.T. C++) Java verwendet keine expliziten Pointervariablen Handhabung von Datenfeldern und Zeichenketten ist anders Keine Präprozessordirektiven und Headerdateien bei Java Java verwendet packages als Programm“sammlungen“ z.T. andere Datentypen (boolean) Keine Strukturen (nicht nötig, da mit Klassen gearbeitet wird) Prof. Martin Trauth Folie 6 / 25 Informatik 2 – Teil 1 Objektorientiertes Programmieren und Grundlagen von Java 1.6 Primitive Datentypen Die wichtigsten sog. primitiven (vordefinierten) Datentypen: char 2 Byte wird vor allem für Zeichen verwendet (Unicode-Codierung!) byte 1 Byte Ganzzahlen zwischen –128 und 127 int 4 Byte (immer!) Ganzzahl (auch negativ) long 8 Byte (immer!) Ganzzahl (auch negativ) mit größerem Wertebereich float 4 Byte Fließkommazahl double 8 Byte präzise Fließkommazahl boolean 1 Byte Datentyp für logische Werte (kann nur die Werte true oder false haben) Unterschiede zu C: Es gibt keine Modifikatoren, mit denen man Ganzzahltypen auf den positiven Wertebereich beschränken kann. In Java kann man stets auch negative Zahlen in long- oder int-Variablen speichern. Sehr wesentlich ist der Typ boolean: Diesen Typ haben in Java alle Logikausdrücke, denn ihr Ergebnis kann immer nur true (wahr) oder false (falsch) sein. Auch Variable (des Typs boolean) können diese Werte annehmen. Wo Logikausdrücke verwendet werden (z.B. in if-Anweisungen) können daher in Java keine Ganzzahl-Werte eingesetzt werden. Unicode ist ein Code für Zeichen. Statt 128 Zeichen, wie mit ASCII- und ANSI-Codierung können in Unicode 65536 Zeichen dargestellt werden. Die ersten 64 Zeichen entsprechen aber der ASCII-Tabelle. Prof. Martin Trauth Folie 7 / 25 Informatik 2 – Teil 1 Objektorientiertes Programmieren und Grundlagen von Java 1.7 Syntax von Klassen Klassen sind die grundlegenden Strukturen des Programmierens in Java (und auch anderen OOP-Sprachen). Ihr grundsätzlicher Aufbau wird an einem Beispiel erläutert. Die Klasse heißt „Auto“. public class Auto { public String name; public int leistung; public int lebensalter; } Die Grundstruktur der Klasse ähnelt sehr einer Strukturdefinition. Tatsächlich gibt es viele Gemeinsamkeiten zu Strukturen, aber Klassen können neben Variablen auch noch Methoden enthalten. Einige Hinweise zur üblichen Schreibweise: Klassennamen werden groß geschrieben (hier: Auto), während Variablennamen (Eigenschaftsnamen) klein geschrieben werden. String ist ebenfalls eine Klasse (kein integraler Datentyp), die Zeichenketten-Objekte generieren kann (siehe nachfolgendes Kapitel). Die sonstige Schreibweise von Namen ist im Wesentlichen wie bei C. Die Variablen name, leistung und lebensalter sind die Klasseneigenschaften und werden beim Erzeugen von Objekten zu Objekteigenschaften. Das Schlüsselwort public definiert den Zugriffsmodus: fremde Objekte können auf die Eigenschaften eines Objekts der Klasse Auto zugreifen (d.h. sie lesen und verändern). Prof. Martin Trauth Folie 8 / 25 Informatik 2 – Teil 1 Objektorientiertes Programmieren und Grundlagen von Java 1.8 Methoden Die Klasse „Auto“ enthält bisher nur Eigenschaften. Es können auch Methoden definiert werden. Als Beispiel wird eine Methode tuneUp() gezeigt, welche die Leistung erhöht (mit Parameter), sowie eine Methode getLeistung(), welche die Leistung als Rückgabewert hat (Parameter- und Rückgabewerte werden wie in C gehandhabt). public class Auto { public String name; public int leistung; pow ist Parameter der Methode tuneUp. Es ist keine Eigenschaft des aus der Klasse Auto abgeleiteten Objekts. public int lebensalter; public void tuneUp(int pow) { this.leistung = this.leistung + pow; } Das Schlüsselwort „this“ in this.leistung bedeutet, dass die Eigenschaft leistung zum gleichen Objekt gehört wie die Methode tuneUp() . Man kann es auch weglassen, aber es macht größere Programme übersichtlicher. public int get_leistung() { return this.leistung; } } getleistung() hat einen Rückgabewert, aber keinen Parameter. Man kann natürlich auch Methoden programmieren die sowohl Rückgabewert als auch (einen oder mehrere) Parameter besitzen. Prof. Martin Trauth Folie 9 / 25 Informatik 2 – Teil 1 Objektorientiertes Programmieren und Grundlagen von Java 1.9 Erzeugung von Objekten Ein Objekt der Klasse „Auto“ könnte z.B. ein ganz bestimmtes Auto sein. Nennen wir das zu erzeugende Objekt daher autoST328. Auto autoST328; autoST328 = new Auto(); Diese Zeile deklariert autoST328 als Referenz auf die Klasse Auto. Mit anderen Worten: autoST328 ist ein „Auto“. Aber es ist noch kein bestimmtes Auto „erzeugt“ worden. Es gibt noch kein Objekt. Nun wird das Objekt autoST328 erzeugt. Das geschieht mit den Schlüsselwort new. Die Klammern hinter Auto weisen auf eine Methode hin. Tatsächlich wird eine spezielle Methode ausgeführt: der Konstruktor (siehe 1.11). Man kann die beiden Zeilen in einer einzigen kombinieren: Auto autoST328 = new Auto(); So schnell kommt man zu einem neuen Auto – leider nur zu einem ziemlich virtuellen. Wichtig: erst wenn ein Objekt erzeugt ist, kann man auf dessen Eigenschaften und Methoden zugreifen (und auch das evtl nur wenn sie als public deklariert wurden). Es gibt auch so genannte (als static deklarierte) Klassenmethoden und Klasseneigenschaften, die ohne Erzeugung eines Objekts verwendet werden können (s. nachfolgendes Kapitel). Prof. Martin Trauth Folie 10 / 25 Informatik 2 – Teil 1 Objektorientiertes Programmieren und Grundlagen von Java 1.10 Zugriff auf Objekteigenschaften Will man nun auf die Objekteigenschaften zugreifen (lesen oder schreiben), dann wird dazu eine ähnliche Syntax wie bei Strukturen in C verwendet: ein Punktoperator zwischen Objektname und Eigenschaftsname. So wird z.B. die Eigenschaft lebensalter auf einen Wert gesetzt: autoST328.lebensalter = 5; Und so wird sie gelesen: alter = autoST328.lebensalter ; Diese Syntax gilt für Zugriff von anderen Objekten aus. Falls eine Methode auf eine Eigenschaft des gleichen Objekts zugreifen möchte kann man den reinen Eigenschaftsnamen nehmen (es sei denn es existiert eine Methodenvariable gleichen Namens) oder this. vor den Namen setzen (siehe auch 1.11). Prof. Martin Trauth Folie 11 / 25 Informatik 2 – Teil 1 Objektorientiertes Programmieren und Grundlagen von Java 1.11 Der Konstruktor Eine sehr wichtige Methode ist der Konstruktor. Er wird immer bei der Erzeugung eines neuen Objekts aufgerufen und trägt den Namen der Klasse (daran kann man ihn im Programmtext erkennen). Seine Parameter werden beim Erzeugen eines Objekts übergeben. Falls kein Konstruktor definiert ist, setzt Java bei der Objekterzeugung einen StandardKonstruktor ein (der keine Parameter hat!). Bei unserer Auto-Klasse wäre es z.B. vorteilhaft, wenn die Objekteigenschaft „Leistung“ bereits bei der Erzeugung des Objekts einen Wert bekommt. Das tut dieser Konstruktor: public Auto(int leistung) { this.leistung = leistung; } Hinweis: der Parameter leistung hat nichts mit der Objekteigenschaft leistung zu tun. Durch this.leistung wird ganz klar auf die Objekteigenschaft leistung zugegriffen. Hier besteht also eine Notwendigkeit das Schlüsselwort this zu verwenden. Natürlich nur dann wenn, wie in unserem Beispiel, der gleiche Name für die Objekteigenschaft wie für den Parameter verwendet wurde. Bei Namensgleichheit und ohne Verwendung von this. überdecken die Namen von Methoden-Variablen (dazu zählen auch die Parameter) die Namen der Objekteigenschaften. Die Erzeugung eines Objekts sieht dann so aus: Auto meinAuto = new Auto(100); Das so generierte Objekt meinAuto der Klasse Auto hat nun den Wert 100 (kW) für die Eigenschaft leistung. Prof. Martin Trauth Folie 12 / 25 Informatik 2 – Teil 1 Objektorientiertes Programmieren und Grundlagen von Java 1.12 Kapselung In der Klasse Auto wurde eine Methode get_leistung() definiert, mit der man die Eigenschaft leistung auslesen kann. Man könnte sich fragen wozu, denn mit einem Zugriff per Punktoperator (siehe 1.10) kann die Eigenschaft doch gelesen werden. Das ist aber nur der Fall, weil die Eigenschaft durch den Modifikator public für Zugriffe fremder Objekte freigegeben ist. Das ist jedoch schlechter OOP-Stil und wurde hier nur zu Demonstrationszwecken verwendet. Eigentlich sollten Eigenschaften durch den Modifikator private nur für Zugriff des eigenen Objekts freigegeben sein. Wollen externe Objekte zugreifen, dann müssen sie das per Objektmethode tun. Diese ist dann natürlich public. Das hat den Vorteil, dass man den Zugriff auf Objekteigenschaften kontrollieren kann. Mit get_leistung kann man z.B. den Leistungswert nur lesen, nicht verändern. Die Objekteigenschaften sind gekapselt: OOP-Prinzip der Kapselung. Zugriffs-Modifikatoren für Eigenschaften und Methoden: Standard (kein Modifikator angegeben) Zugriff durch Objekte oder Klassen im gleichen package * private Zugriff nur vom gleichen Objekt bzw. der gleichen Klasse protected Zugriff durch Objekte und Klasse der gleichen oder einer abgeleiteten Klasse (s. 1.14), oder aus dem gleichen package * heraus. public Zugriff durch alle Objekte oder Klassen * package: Ordnungsstruktur in Java, wird später erläutert Prof. Martin Trauth Folie 13 / 25 Informatik 2 – Teil 1 Objektorientiertes Programmieren und Grundlagen von Java 1.13 Kapselung – Beispiel-Schema Objekt der Klasse Auto private: Eigenschaft leistung Zugriff public: Methode get_leistung() Aufruf Rückgabewert anderes Objekt Aufruf: get_leistung() Prof. Martin Trauth Folie 14 / 25 Informatik 2 – Teil 1 Objektorientiertes Programmieren und Grundlagen von Java 1.14 abgeleitete Klassen (Kindklassen), Vererbung Am eingangs erwähnten Beispiel eines Objekts aus der Natur, dem Elefanten, kann man gut ein wichtiges Verfahren der OOP erläutern: die Vererbung. Nehmen wir an, es gäbe bereits eine Klasse „Tier“ mit dazu passenden Methoden und Eigenschaften. Dann müßte man für die Klasse „Elefant“ nicht alles neu erfinden. Der Elefant ist ja zweifellos ein Tier, also sind alle in der Tier-Klasse definierten Eigenschaften (z.B. Gewicht) und Methoden (z.B. Fressen) auch auf ihn anwendbar. Aber der Elefant hat eventuell zusätzliche Eigenschaften, z.B. eine Rüssellänge. Oder zusätzliche Methoden, z.B. das Trompeten. Umgesetzt auf OOP und Java kann man abgeleitete Klassen bilden (Kindklassen), welche die Eigenschaften und Methoden ihrer Superklasse (Elternklasse) erben. Das ist das wichtige OOP-Prinzip der Vererbung. Zusätzlich können Sie in Kindklassen weitere Eigenschaften und/oder Methoden definieren. Das geschieht durch Verwendung des Schlüsselworts extends (erweitert), woraus bereits hervorgeht, dass eine Kindklasse eine Erweiterung bzw. Spezialisierung der Elternklasse darstellt. Ein reines Kopieren wäre auch ziemlich sinnlos, denn aus einer Klasse lassen sich ohnehin beliebig viele Objekte erzeugen. Aus unserer Beispielklasse „Auto“ lässt sich die Kindklasse „Transporter“ ableiten. class Transporter extends Auto { private int maxZuladung; } Es wurde die zusätzliche Eigenschaft maxZuladung definiert. Ebenso ist es möglich zusätzliche Methoden zu definieren. Hinweis: Konstruktoren werden nicht vererbt und müssen im Bedarfsfall neu definiert werden. Prof. Martin Trauth Folie 15 / 25 Informatik 2 – Teil 1 Objektorientiertes Programmieren und Grundlagen von Java 1.15 Kindklassen – Überschreiben von Methoden Nicht nur neue Methoden kann man in einer Kindklasse definieren, sondern auch vorhandene überschreiben. Hinweis: das Überschreiben von Methoden ist etwas anderes als das Überladen, das später erklärt wird. Am Beispiel der Klasse Transporter: die Methode set_zuladung() wird hinzu gefügt, die ererbte Methode tuneUp() überschrieben. class Transporter extends Auto { Der Programmtext der Elternklasse muss natürlich irgendwo im gesamten Programmcode enthalten sein (wenn sie nicht durch package-import geladen wird). Es spielt aber keine Rolle, ob ihr Programmtext vor oder hinter der Kindklasse steht. private int maxZuladung; public void set_zuladung(int gewicht) { this.maxZuladung = gewicht; } public void tuneUp(int pow) { if (pow > 1000) pow = 1000; // Limitierung auf 1000 kW this.leistung = pow; } } Das Überschreiben von Methoden ist ein sehr häufiges Verfahren wenn man fertige Klassen aus Klassenbibliotheken übernimmt. Man leitet eine Kindklasse ab und kann in dieser durch Überschreiben Änderungen vornehmen. Prof. Martin Trauth Folie 16 / 25 Informatik 2 – Teil 1 Objektorientiertes Programmieren und Grundlagen von Java 1.16 Die Methode main(), Klasseneigenschaften und Methoden Die bisherigen Beispiele starten unter normalen Betriebssystemen nicht. Dazu wird, wie in C, eine Hauptfunktion main() benötigt. In Java wird „Methode“ statt „Funktion“ gesagt. Java verlangt die komplette Parameterliste für main(). Leere Klammern werden von vielen Compilern als Fehler bewertet, auch wenn man die Kommandozeilen-Parameter selten benötigt. Ein einfaches Beispiel für main(): class MeinTest1 { public static void main(String[] args) { System.out.println("Berechne 7 * 2:" + 7 * 2); Siehe 1.17 } } In Java baut alles auf Klassen auf. Also befindet sich auch die Methode main() in einer Klasse, der man normalerweise den Namen des Programms gibt. Man fügt dann weitere Klassen an, mit denen man die gewünschten Objekte erzeugen kann. Die Methode main() ist aber keine Objektmethode, da sie mit dem Modifikator static deklariert wurde. Sie ist eine so genannte Klassenmethode. Man kann sie mit der Syntax <Klassenname>.main() aufrufen (das tut aber in der Regel das Betriebssystem oder das Entwicklungssystem). Mit dem Modifikator static können auch Klasseneigenschaften deklariert werden. Klasseneigenschaften und –methoden werden bei der Erzeugung von Objekten nicht zu Objekteigenschaften oder Objektmethoden. Würde man ein Objekt der Klasse MeinTest1 erzeugen, so hätte es weder Eigenschaften noch Methoden. Man verwendet Klasseneigenschaften und –methoden, wenn man sie nur einmal benötigt und nicht in viele Objekte kopieren möchte. Prof. Martin Trauth Folie 17 / 25 Informatik 2 – Teil 1 Objektorientiertes Programmieren und Grundlagen von Java 1.17 Die Standard-Ausgabe Die Standard-Ausgabe-Methoden lauten System.out.println() und System.out.print(). „System.out“ ist das Objekt dazu. Es ist ein automatisch (von der Java-VM) erzeugtes Objekt, deswegen auch die ungewöhnliche Syntax mit dem Klassennamen System im Objektnamen. println() gibt immer eine neue Zeile aus. print() fügt die Ausgabe dort an, wo die letzte Ausgabe endete. Als Parameter werden Zeichenketten und/oder Ausdrücke verwendet, die durch +Zeichen verbunden werden. Platzhalter für die Ausdrücke werden nicht benötigt. Alle aus C bekannten Steuerzeichen (z.B. \n) können verwendet werden. Die Ausgabe des Beispiels System.out.println("Berechne 7 * 2:" + 7 * 2); ist: Berechne 7 * 2: 14 Prof. Martin Trauth Folie 18 / 25 Informatik 2 – Teil 1 Objektorientiertes Programmieren und Grundlagen von Java 1.18 Beispiel eines Java-Programms I Für unser Beispiel benötigen wir die vollständige Beispiel-Klasse „Auto“. Sie ist daher hier aufgeführt: public class Auto { private String name; private int leistung; private int lebensalter; public Auto(int leistung) { this.leistung = leistung; } public void tuneUp(int pow) { this.leistung = this.leistung + pow; } public int get_leistung() { return this.leistung; } } Prof. Martin Trauth Folie 19 / 25 Informatik 2 – Teil 1 Objektorientiertes Programmieren und Grundlagen von Java 1.19 Beispiel eines Java-Programms II Die main-methode in der Klasse „MeinTest2“ erzeugt ein Objekt der Klasse „Auto“ und arbeitet mit dessen Methoden. class MeinTest2 { public static void main(String[] args) { Objekt wird erzeugt! Auto meinAuto = new Auto(75); System.out.println("Leistung: " + meinAuto.get_leistung() + "kW"); meinAuto.tuneUp(50); System.out.println("getunte Leistung: " + meinAuto.get_leistung() Man kann problemlos in neuer Zeile weiter schreiben. + "kW"); } } Die Ausgabezeilen dieses Programms sehen so aus: Leistung: 75kW getunte Leistung: 125kW Prof. Martin Trauth Folie 20 / 25 Informatik 2 – Teil 1 Objektorientiertes Programmieren und Grundlagen von Java 1.20 Logikoperationen und der Typ boolean Logikausdrücke haben in Java das Ergebnis true oder false. Will man diese Werte speichern, benötigt man eine Variable vom Typ boolean. Wenn man die Werte ausgeben läßt, werden sie als true oder false dargestellt. Ein Beispiel: class MeinTest3 { public static void main(String[] args) { int a = 5, b = 10; boolean bool1; System.out.println("a < b: " + (a < b)); System.out.println("a == b: " + (a == b)); bool1 = a >= b; System.out.println("a >= b: " + bool1); } } Die Ausgabezeilen dieses Programms: a < b: true a == b: false a >= b: false Prof. Martin Trauth Folie 21 / 25 Informatik 2 – Teil 1 Objektorientiertes Programmieren und Grundlagen von Java 1.21 Pseudokonstanten, Schlüsselwort final Wenn man in Java eine Variable unveränderbar machen möchte, sie also als Konstante benutzt, dann verwendet man das Schlüsselwort final in ihrer Deklaration. Sie kann dann nur einmal einen Wert zugewiesen bekommen. Jede folgende Wertzuweisung würde einen Compilerfehler auslösen. Man spricht von konstanten Variablen oder Pseudokonstanten. Beispiel: final double UST_SATZ = 19. ; Deklaration und Wertzuweisung in einer Zeile. final char EURO; EURO = ‘€‘; Deklaration und Wertzuweisung getrennt. Konstantennamen werden wie in C üblicherweise mit Großbuchstaben geschrieben (final funktioniert genau so wie const in C). Auch die Schreibweise einzelner Zeichen in einfachen Hochkommata entspricht der C-Schreibweise. Prof. Martin Trauth Folie 22 / 25 Informatik 2 – Teil 1 Objektorientiertes Programmieren und Grundlagen von Java 1.22 Klassenpakete (packages) verwenden Klassenpakete (packages) sind Sammlungen von Klassen. Ihre Hauptbedeutung haben sie als Bestandteile von Klassenbibliotheken. Die Packages sind so etwas wie die Bücher in der Java-Bibliothek. Sie fassen Klassen zusammen, die zu einem Thema gehören. Paketnamen werden klein geschrieben und können aus mehreren Namensbestandteilen zusammengesetzt sein, die durch Punkte getrennt werden. Beispiele: java.lang grundlegende Klassen von Java java.math Mathematik-Klassen java.awt.event Ereignisbehandlung Will man eine oder mehrere Klassen aus einem solchen Paket verwenden, dann muss man es importieren . Dazu schreibt man das Schlüsselwort import vor <paketname>.<Klassenname> oder <paketname>.* (dann werden alle Klassen des Pakets importiert). Wichtig: die import-Anweisung muss vor nachfolgenden Klassendefinitionen stehen, die Klassen des Pakets verwenden. Das paket java.lang wird automatisch verwendet, das muss man nicht explizit importieren. import java.awt.event.*; // alle Klassen des Pakets werden importiert import java.applet.Applet; // nur die Klasse Applet wird importiert public class MeineKlasse { /* Code der Klasse */ } Eine Klasse im importierten Paket muss als public definiert sein, sonst kann sie von einer anderen Klasse nur dann verwendet werden wenn diese dem gleichen Paket angehört. Prof. Martin Trauth Folie 23 / 25 Informatik 2 – Teil 1 Objektorientiertes Programmieren und Grundlagen von Java 1.23 Packages erstellen Man kann auch eigene Packages erstellen. Dazu wird im Quelltext vor allen Importanweisungen das Schlüsselwort package, gefolgt vom gewünschten Paketnamen geschrieben. Beispiel: package myPackage.first; import java.awt.*; public class MeineKlasse1 { /* Code der Klasse */ } Der Programmcode wird dann im Unterordner myPackage\first des aktuellen Arbeitsverzeichnisses gespeichert. Dieses Unterverzeichnis muss man selbst erstellen, es sei denn das Java-Entwicklungssystem sorgt dafür. Importiert ein anderes Programm dieses Paket, dann wird es dort gesucht. Liegt dieses importierende Programm aber in einem anderen Arbeitsverzeichnis, dann muss man dem Compiler durch Angabe eines classpath das Package-Verzeichnis mitgeteilen (das Thema soll aber hier nicht weiter vertieft werden. Bei Interesse bitte Fachliteratur lesen). Es können auch bereits compilierte Java-Klassen (Bytecode, Extension .class) im Paketverzeichnis gespeichert werden. Wenn sie importiert werden, muss der Compiler nicht mehr übersetzen. Packages mit dem ersten Teil java oder javax liegen in einem speziellen Bibliotheksverzeichnis, das dem Compiler und der VM bekannt ist. In dem Fall braucht man sich nicht um den Suchpfad zu kümmern. Diese Bibliotheks-Packages sind immer compiliert und zusätzlich in Archiv-Dateien komprimiert (Extension .jar). Prof. Martin Trauth Folie 24 / 25 Informatik 2 – Teil 1 Objektorientiertes Programmieren und Grundlagen von Java 1.24 Bemerkungen zur Wortwahl In der Literatur werden die gleichen Sachverhalte in Java leider verschieden bezeichnet. Statt von Objekten wird z.T. von Instanzen (einer Klasse) geschrieben. Eigenschaften werden manchmal (Objekt-) Variable genannt. Außerdem gibt es alle möglichen Kombinationen dieser Bezeichnungen, z.B. Instanzvariable – was das gleiche ist wie eine Objekteigenschaft. Spezialisten unterscheiden zwischen Instanzen und Objekten. Die Bedeutungen sind etwas verschieden – jedenfalls für Spezialisten. Für die meisten Fälle (und auch in diesem Skript) sind solche Details nicht wichtig. Schon deshalb weil sich die Spezialisten ohnehin nie einig sind.... Einig ist man sich (weitgehend) darin, dass man von Methoden statt von Funktionen spricht und schreibt. Variablen und Eigenschaften sind aber durchaus verschieden. Eine Variable ist alles was einen Wert speichern kann. Daher sind in OOP alle Eigenschaften Variable. Aber umgekehrt beschreibt nicht jede Variable eine Eigenschaft. Auch Methoden können interne Variable benutzen. Diese werden aber nicht zu Objekt- oder Klasseneigenschaften. Prof. Martin Trauth Folie 25 / 25