Programmiervorkurs SS 2011
Objekte und Vererbung Programmiervorkurs SS 2011
Wir erinnern uns an Montag public class HelloWorld { public static void main(string[] args) { System.out.println("Hello World!"); public class NAME { public static void main(string[] args) { Wenn das Programm gestartet wird, dann muss der Java-Interpreter wissen wo es eigentlich los geht Deshalb heißt die Start-Methode main public static void und (String[] args) sind für uns vorerst einfach mal fest vorgegeben und müssen immer da stehen Erklärung folgt später! Erklärung kommt heute! auch hier wieder: was in geschweiften Klammern steht ist das, was getan werden soll 3
Mehrere Java Klassen Programmiervorkurs SS 2011 4
Mehrere Java Klassen Wir kennen bisher nur Java Programme bestehend aus einer Datei Wie schaut es also aus wenn wir mehrere Dateien verwenden wollen? 5
Mehrere Java Klassen public class Eins { public static void main(string[] args) { System.out.println("Hauptklasse!"); System.out.println(Zwei.methode()); public class Zwei { public static String methode() { return "Und ich bin die 2. Klasse!"; :> javac Eins.java :> java Eins Hauptklasse! Und ich bin die 2. Klasse! 6 Wir müssen zum compilieren nur diejenige Klasse compilieren, welche die main-methode enthält nur eine Datei muss eine main-methode haben die andere Datei darf Java erkennt und setzt Links zwischen den zugehörigen Dateien von selbst
Mehrere Java Klassen public class HauptKlasse { public static void main(string[] args) { int add = MatheKlasse.add(2, 4); int sub = MatheKlasse.sub(2, 4); int by = MatheKlasse.by(2, 4); public class MatheKlasse { public static int add(int a, int b) { return a + b; public static int sub(int a, int b) { return a - b; public static int by(int a, int b) { return a * b; Die zweite Klasse kann ganz normal mit Methoden gefüllt werden, die von der ersten Klasse aus aufgerufen werden können NAME_ZWEITE_KLASSE. methoden_name(parame TER_LISTE) Im Prinzip nichts anders als das, was wir schon können 7
public vs. private public class Hauptprogramm { public static void main(string[] args){ Versteckprogramm.run(); // nicht moglich: //Versteckprogramm.doSomeWork(); public bezeichnet, dass die Methoden oder Klassen von überall und von jedem benutzt werden dürfen public class Versteckprogramm { public static void run() { dosomework(); private static void dosomework() { System.out.println ("Unsichtbar von außen!"); mit private werden Methoden nach außen hin versteckt nur Methoden in der gleichen Klasse dürfen andere private Methoden benutzen 8
Statische Variablen Programmiervorkurs SS 2011 9
Statische Variablen public class StaticVariable { public static int i = 0; auf statische Variablen { public static void main(string[] args) System.out.println(i); increaseby(2); increaseby(3); System.out.println(i); halfi(); System.out.println(i); haben alle Methoden einer Klasse Zugriff wenn eine Methode die Variable ändert, dann public static void increaseby(int value) { i += value; müssen alle anderen Folge-Aufrufe mit public static void halfi() { i /= 2; dieser Änderung leben 10
statische Variablen schützen public class Worker { public static void main(string[] args) { WorkCounter.doSomething(); WorkCounter.doSomething(); WorkCounter.doSomething(); System.out.println (WorkCounter.getWorkAmount()); public class WorkCounter { private static int counter = 0; public static void dosomething() { counter++; // working public static int getworkamount() { return counter; mit private kann ich statische Variablen gegen unkontrollierte Änderungen schützen alle Methoden der eigenen Klasse können aber ungehindert auf die Variable zugreifen 11
static und... nicht static Programmiervorkurs SS 2011 12
Konto public class StupidKonto { public static void main(string[] args) { int konto = 0; konto += 100; konto -= 20; Wir wollen eine Art Konto programmieren z.b. ein Bankkonto, auf dass wir einzahlen und abheben können Das ist so aber nicht schön, denn was macht man bei mehreren Konten? Mehrere Variablen für die Konten? Was mache ich wenn ich die Anzahl maximaler Konten nicht kenne? 13
Idee Wir brauchen eine Möglichkeit mehrere Konten zu erstellen beliebig viele und ich muss sie mir merken können Konto Schablonen! 14
Konto Schablone Ich definiere mir eine Schablone für ein Konto und wenn ich ein Konto brauche... dann nutze ich meine Schablone um ein neues Konto zu erstellen 15
Konto Schablone Konto Schablone Konto Instanz Konto Instanz Konto Instanz Ich erzeuge mir von einer Schablone beliebig viele Instanzen EINE Instanz nennt man auch ein Objekt
Konten mit eigenem Speicher public class Bank { public static void main(string[] args) { Konto k1 = new Konto(100); Konto k2 = new Konto(20); k1.einzahlen(50); k2.abheben(40); System.out.println(k1.guthaben()); System.out.println(k2.guthaben()); public class Konto { private int konto; public Konto(int startguthaben) { konto = startguthaben; public void einzahlen(int betrag) { konto += betrag; public void abheben(int betrag) { konto -= betrag; public int guthaben() { return konto; :> javac Bank.java :> java Bank 150-20 17
Konto Schablone Konto Schablone erzeugen einer Instanz mit new Konto(...) Konto Instanz Konto Instanz Konto Instanz Jedes Konto hat eine eigene Variable für den Kontostand Mit new wird aus dem Bauplan ein Objekt instanziiert (= erzeugt) Jedes Objekt hat im Arbeitsspeicher einen eigenen Bereich für seine Variablen 18
Was passiert im RAM public class Bank { public static void main(string[] args) { Konto k1 = new Konto(100); Konto k2 = new Konto(20); k1.einzahlen(50); k2.abheben(40); System.out.println(k1.guthaben()); public class Konto { private int konto; System.out.println(k2.guthaben()); eigener public class Konto { private int konto; { public Konto(int startguthaben) konto = startguthaben; Zustand! { public Konto(int startguthaben) konto = startguthaben; public void einzahlen(int betrag) { konto += betrag; public void abheben(int betrag) { konto -= betrag; public int guthaben() { return konto; public void einzahlen(int betrag) { konto += betrag; public void abheben(int betrag) { konto -= betrag; public int guthaben() { return konto;
Der Konstruktor public Konto(int startguthaben) { konto = startguthaben; Warum gibt es hier kein static und keinen Rückgabetyp? Ein Konstruktor erzeugt ein Objekt, eine Instanz der Java- Klasse Ein Konstruktor ist keine Methode Der Konstruktor hat keinen Rückgabetyp Wenn schon, dann ist der Rückgabetyp das erzeugte Objekt Der Konstruktor Name muss identisch sein mit dem Java-Klassen Namen 20
Ein neuer Datentyp public class Bank { public static void main(string[] args) { Konto k1 = new Konto(100);... public class Konto { private int konto; public Konto(int startguthaben) { konto = startguthaben;... Wir erinnern uns Dateiname = Klassenname Klassenname = Konstruktor-Name Unser neues Objekt new Konto(100) ist von Typ Konto wir haben also nicht mehr nur int, double, String zur Verfügung 21
Methoden von Objekten public class Bank { public static void main(string[] args) { Konto k1 = new Konto(100);... System.out.println(k1.guthaben()); public class Konto {... public void einzahlen(int betrag) { konto += betrag;... public int guthaben() { return konto; Bisher wurden Methoden nur über den Namen aufgerufen oder direkt auf einer Klasse aufgerufen Jetzt können wir Methoden von Objekten aufrufen VARIABLEN-NAME. METHODENNAME ( PARAMETER ) 22
Beispiele Programmiervorkurs SS 2011 23
int[] i = new int[]; Bekanntes Integer.valueOf(...); System.out.println(...); Keine Angst! Ihr habt es schon benutzt ohne zu wissen was es ist Dann gehts es jetzt erst recht! 24
Stringvergleich public class StringEquals { public static void main(string[] args) { String t_string = "text"; if (t_string.equals("text")) { System.out.println("identisch"); else { System.out.println("nicht identisch"); Beim Strings vergleichen muss.equals(...) verwendet werden sonst vergleichen wir Speicherpositionen im RAM Ein String ist ein Objekt eigentlich ein Array von Chars 25
Vorgefertigte Klassen import java.util.random; public class Zufall { public static void main(string[] args) { Random rand = new Random(); // Zufallszahl zwischen 0 und 2 System.out.println(rand.nextInt(3)); // Zufallszahl zwischen 0 und 4 System.out.println(rand.nextInt(5)); // Zufallszahl zwischen 0.0 und 1.0 System.out.println(rand.nextDouble()); Klasse Random existiert schon auf unserem PC muss jedoch extra eingebunden werden Wir können uns von ihr ein Objekt erzeugen und benutzen 26
Wann ist etwas static Wann ist etwas nicht static Programmiervorkurs SS 2011 27
statisch / nicht statisch statisch = unveränderlich alles was einen internen Zustand hat ist nicht statisch ein Konto hat einen Kontostand Math.pow(3,4); liefert jedes mal das gleiche Ergebniss Math.pow(a,b) hat keinen inneren Zustand es merkt sich nicht, was wir bisher damit gemacht haben Math ist kein Objekt sondern nur eine Klasse deren Methoden wir direkt nutzen 28
Zugriffsproblem Programmiervorkurs SS 2011 29
this public class User { public static void main(string[] args) { Container c = new Container(5); c.setint(7); System.out.println(c.getInt()); public class Container { private int i = 0; public Container(int i) { this.i = i; Wenn in einem Bereich zwei verschiedene Variablen den gleichen Namen haben eine lokale Variable eine globale Variable public int getint() { return i; public void setint(int i) { this.i = i; dann können wir mit this entscheiden welche wir meinen 30
JETZT GEHTS ERST RICHTIG LOS 31
KarelJ Programmiervorkurs SS 2011 32
KarelJ Jetzt wollen wir mal richtig los legen Objekte erstellen und damit etwas tun KarelJ ist eine kleine Graphik-Bibliothek, die es erlaubt einen kleinen Roboter über eine Karte zu bewegen Karel kann außerdem Beeper ablegen und wieder aufnehmen Und in Karels Welt gibt es Wände Sagt Hallo zu KarelJ 33
Karels Welt 34
.move() Was kann Karel? einen Schritt in Blickrichtung.turnLeft() 90 nach links drehen.pickbeeper().putbeeper() Beeper aufnehmen/ablegen 35
Was kann Karel?.nextToABeeper() return boolean steht Karel über mindesten einem Beeper?.anyBeepersInBeeperBag() return boolean sind weitere Beeper im Rucksack? 36
Was kann Karel?.facingNorth().facingSouth().facingEast() return boolean return boolean return boolean.facingwest() return boolean schaut Karel nach Norden/Süden/Osten/Westen=.frontIsClear() return boolean steht Karel vor eine Wand? (in Sichtrichtung) 37
Karel in Aktion public class KarelAction { public static void main(string[] args) { World.setSize(6, 8); // Größe der Karte festlegen World.setDelay(500); // Geschwindigkeit von Karel festlegen World.setTrace(false); // Debug Ausgabe an/aus schalten Robot r = new Robot(1, 2, 5, direction.north); r.move(); r.move(); r.putbeeper(); r.move(); r.turnleft(); r.move(); System.out.println("Wand: " + r.frontisclear()); 38
Der Karel Constructor Robot r = new Robot(1, 2, 5, direction.north); Wir erzeugen eine Variable vom Typ Robot mit Namen r Wir instanziieren ein Objekt vom Typ Robot und speichern es in die Variable r street - die x-koordinate avenue - die y-koordinate beeper - Anzahl Beeper im Rucksack looking - Richtung, in die Karel am Anfang schaut direction.north, direction.south, direction.east, direction.west 39
Karel starten? Wie compiliert man das jetzt? Ihr benötigt die Datei robots.jar von der Material-Seite Windows :> javac classpath robots.jar; KarelAktion.java :> java classpath robots.jar; KarelAktion Unix/Linux :> javac classpath ~/robots.jar:. KarelAktion.java :> java classpath ~/robots.jar:. KarelAktion Unten im Pool, wenn ihr die.bashrc und robots.jar ins home Verzeichnis entpackt habt :> compilerobot KarelAktion.java :> runrobot KarelAktion 40
TurnRightRobot Programmiervorkurs SS 2011 41
rechts rum geht nicht Wir haben gesehen, dass sich Karel nach links drehen kann Aber nach rechts gibt es nicht, wäre aber schon praktisch Wir müssen diese Funktion selbst implementieren Wir schreiben eine neue TurnRightRobot-Klasse, die nach rechts drehen enthält und lassen diese TurnRightRoboter- Klasse alle Eigenschaft von der Robot-Klasse erben 42
TurnRightRoboter public class TurnRightRobot extends Robot { public TurnRightRobot(int arg0, int arg1, int arg2, direction arg3) { super(arg0, arg1, arg2, arg3); public void turnright() { turnleft(); turnleft(); turnleft(); public class TurnRightMain { public static void main(string[] args) { TurnRightRobot r = new TurnRightRobot(2, 2, Integer.MAX_VALUE,direction.NORTH); r.move(); System.out.println("Ich kann mich jetzt rechts herum drehen..."); r.turnright(); r.move(); 43
extends und super In der Java Klasse TurnRightRoboter wurde rechts drehen mittels 3 mal links drehen implementiert Aber in der ganze Klasse sind die bekannten Methoden move(), putbeeper() etc. nicht enthalten, warum? public class TurnRightRoboter extends Robot { public TurnRightRoboter(int arg0, int arg1, int arg2, direction arg3) { super(arg0, arg1, arg2, arg3); Die Klasse TurnRightRobot extends (erweitert) die Klasse Robot d.h. dass die neue Klasse alle Methoden, globalen Variablen und sonstigen Eigenschaften von der Klasse Robot erbt 44
Vererbung Alles was zweibeinig ist, ist auch automatischein Säuger und ein Lebewesen Vererbung entlang des Baumes 45
extends und super public class TurnRightRoboter extends Robot { public TurnRightRoboter(int arg0, int arg1, int arg2, direction arg3) { super(arg0, arg1, arg2, arg3); super ruft den Super-Konstruktor der im Vererbungsbaum darüberliegenden Klasse auf wenn es sich um eine Vererbung handelt es müssen alle Parameter in der richtigen Reihenfolge übergeben werden, die dieser Konstruktor auch erwartet und der super-aufruf muss der erste im Konstruktor sein versteht super nicht als mächtig sondern als darüber 46
TurnRightRobot public class TurnRightRobot extends Robot { public TurnRightRobot(int arg0, int arg1, int arg2, direction arg3) { super(arg0, arg1, arg2, arg3); public void turnright() { turnleft(); turnleft(); turnleft(); extends importiert alle Eigenschaften von Robot super ruft den Konstruktor von Robot auf public static void main(string[] args) { TurnRightRobot r = new TurnRightRobot(2, 2, Integer.MAX_VALUE, direction.north); r.move(); System.out.println("Ich kann mich jetzt rechts herum drehen..."); r.turnright(); r.move();.turnright() auf einer Instanz von TRR steht absofort als Befehl zur Verfügung 47
globale Variablen schützen reloaded public class Worker { public static void main(string[] args) { WorkCounter.doSomething(); WorkCounter.doSomething(); WorkCounter.doSomething(); System.out.println (WorkCounter.getWorkAmount()); public class WorkCounter { private static int counter = 0; public class WorkerNew { public static void main(string[] args) { WorkerNew wn1 = new WorkerNew(); WorkerNew wn2 = new WorkerNew(); wn1.dosomething(); wn1.dosomething(); wn2.dosomething(); System.out.println(wn1.getWA()); System.out.println(wn2.getWA()); public WorkerNew() { this.counter = 0; public static void dosomething() { counter++; // working public static int getworkamount() { return counter; private int counter; public void dosomething() { this.counter++; // working public int getwa() { return this.counter; 48
TreppensteigerRobot public class TreppensteigerRobot extends TurnRightRobot { public TreppensteigerRobot(int arg0, int arg1, int arg2, direction arg3) { super(arg0, arg1, arg2, arg3); private void steigeeinestufe() { putbeeper(); move(); turnright(); move(); public void steigetreppe(int stufen) { for (int i = 0; i < stufen; i++) { this.steigeeinestufe(); Aber funktioniert das auch? public static void main(string[] args) { TreppensteigerRobot r = new TreppensteigerRobot(2, 2, 100, direction.north); r.steigetreppe(5); 49
Zustandserhaltung Das ist KEINE Treppe! Schlagwort: Zustandserhaltung Was ist das? Bsp: Drucker Eurer Mitstudi druckt im Pool 500 Seiten Script aus Ihr wollt als nächstes drucken, aber das Paspier ist aus. Blöd. Euer Mitstudi hätte Papier nachfüllen sollen... verlasst einen Arbeitsplatz so, wie ihr ihn vorgefunden habt, damit Nachfolger keine Probleme haben
Zustandserhaltung Vor der 1. Stufe Nach der 1. Stufe Zustandserhaltung 51
TreppensteigerRobot korrigiert public class TreppensteigerRobot extends TurnRightRobot { public TreppensteigerRobot(int arg0, int arg1, int arg2, direction arg3) { super(arg0, arg1, arg2, arg3); private void steigeeinestufe() { putbeeper(); move(); turnright(); move(); turnleft(); public void steigetreppe(int stufen) { for (int i = 0; i < stufen; i++) { this.steigeeinestufe(); public static void main(string[] args) { TreppensteigerRobot r = new TreppensteigerRobot(2, 2, 100, direction.north); r.steigetreppe(5); 52
Jetzt wird s richtig lustig! 53
Jetzt wird s richtig lustig! Wir wollen ans Ziel: der Doppel-Beeper Laufregeln: Wir laufen bis wir vor einer Wand stehen Liegt ein Beeper unter uns dann laufen wir nach rechts weiter Liegt kein Beeper unter uns dann laufen wir nach links weiter 54
BoingRobot public class BoingRobot extends TurnRightRobot { public BoingRobot(int arg0, int arg1, int arg2, direction arg3) { super(arg0, arg1, arg2, arg3); // go Methode public static void main(string[] args) { World(); BoingRobot r = new BoingRobot(2, 1, 0, direction.north); r.go(); System.out.println("Ziel!"); 55
Die go-methode public void go() { Wir laufen gerade aus, wenn wir keine Wand im Sichtfeld haben move() go() sonst haben wir eine Wand vor uns Wenn wir auf einem Beeper stehen Wenn wir auf einem zweiten Beeper stehen ENDE! sonst stehen wir nicht auf einem zweiten Beeper turnright(); go(); sonst stehen wir auf keinem Beeper turnleft() go() 56
Die go-methode public void go() { if (this.frontisclear()) { this.move(); go(); else haben wir eine Wand vor uns Wenn wir auf einem Beeper stehen Wenn wir auf einem zweiten Beeper stehen ENDE! sonst stehen wir nicht auf einem zweiten Beeper turnright(); go(); sonst stehen wir auf keinem Beeper turnleft() go() 57
Die go-methode public void go() { if (this.frontisclear()) { this.move(); go(); else { if (this.nexttoabeeper()) { this.pickbeeper(); Wenn wir auf einem zweiten Beeper stehen ENDE! sonst stehen wir nicht auf einem zweiten Beeper turnright(); go(); else { this.turnleft(); go(); 58
Die go-methode public void go() { if (this.frontisclear()) { this.move(); go(); else { if (this.nexttoabeeper()) { this.pickbeeper(); if (this.nexttoabeeper()) { this.pickbeeper(); this.turnoff(); sonst stehen wir nicht auf einem zweiten Beeper turnright(); go(); else { this.turnleft(); go(); 59
Die go-methode public void go() { if (this.frontisclear()) { this.move(); go(); else { if (this.nexttoabeeper()) { this.pickbeeper(); if (this.nexttoabeeper()) { this.pickbeeper(); this.turnoff(); else { this.turnright(); go(); else { this.turnleft(); go(); 60
Die go-methode public void go() { if (this.frontisclear()) { this.move(); go(); else { if (this.nexttoabeeper()) { this.pickbeeper(); if (this.nexttoabeeper()) { this.pickbeeper(); this.turnoff(); else { this.turnright(); go(); else { this.turnleft(); go(); 61
That s it for today!