Institut für Programmierungund Reaktive Systeme
Java Grundlagen 2 - OOP
Markus Reschke
20.08.2014
Warum OOP? OOP mit Java Vererbung Abstrakte Klassen und Interfaces
Eine kleine Geschichte1
Spezifikation
Es sollen Formen in einer GUI angezeigt werden: Ein Quadrat, ein Kreisund ein Dreieck. Wenn der Benutzer auf eine Form klickt, so soll diesesich um 360◦ drehen und es soll eine AIF Audiodatei abgespielt werden,welche fur jede Form eine andere ist.
Zwei Programmierer: Larry und Brad
Wer zuerst liefert, bekommt einen neuen Burostuhl.
Larry arbeitet prozedual
Brad arbeitet objektorientiert
1Entnommen aus ”Head First Java - Second Edition”, Kapitel 2
Warum OOP? OOP mit Java Vererbung Abstrakte Klassen und Interfaces
Die erste VersionLarry uberlegt sich: Was muss das Programm machen? WelcheMethoden werden dazu gebraucht? → rotate und playSound
rotate(shapeNum) {
// Rotiere Form um 360 Grad
}
playSound(shapeNum) {
// Schau nach , welche AIF zur Form gehoert
// Spiele Datei ab
}
Brad uberlegt sich: Welche Dinge tauchen im Programm auf? → DieFormen, aber auch der User, der Click, der Sound etc. (diese werdenhier vernachlassigt)
class Triangle {
rotate () {
//Drehe ein Dreieck
}
playSound () {
// Spiele AIF fuer ein
Dreieck ab
}
}
class Circle {
rotate () {
//Drehe einen Kreis
}
playSound () {
// Spiele AIF fuer einen
Kreis ab
}
}
class Square {
rotate () {
//Drehe ein Rechteck
}
playSound () {
// Spiele AIF fuer ein
Rechteck ab
}
}
Warum OOP? OOP mit Java Vererbung Abstrakte Klassen und Interfaces
Aber...
Larry wird als erster fertig. Aber es gibt eine Anderung der Spezifikation:
Erweiterung der Spezifikation
Es soll nun eine amobenartige Form in der GUI geben.Wenn sie angeklickt wird, soll sie sich wie die anderenFormen drehen und eine HIF Sounddatei abspielen.
(Bild aus HFJ)
Warum OOP? OOP mit Java Vererbung Abstrakte Klassen und Interfaces
V2
Larry muss zwar nicht viel anseinem Code andern, aber er mussbereits getesteten und erprobtenCode andern.
1 playSound(shapeNum) {
2 if (/*Form ist keine Amoebe */) {
3 // Schau nach , welche AIF zur Form
gehoert
4 // Spiele Datei ab
5 } else {
6 // Spiele Amoeben HIF Sounddatei ab
7 }
8 }
Brad schreibt eine neue Klasse furdie Amobe. Den bereitsexistierenden Code fur die anderenFormen muss er nicht anfassen.
1 class Amoeba {
2 rotate () {
3 //Drehe Amoebe
4 }
5 playSound () {
6 // Spiele HIF fuer ein Amoebe ab
7 }
8 }
Warum OOP? OOP mit Java Vererbung Abstrakte Klassen und Interfaces
Der Projektmanager schlagt wieder zu
Larry wird wieder als erster fertig. Aber es noch gibt eine Anderung derSpezifikation:
Anderung der Spezifikation
Brad und Larry haben die Amobe um denMittelpunkt des kleinsten Rechtecks um die Amobegedreht. Die Amobe soll sich um einen freifestlegbaren Punkt drehen.
(Bild nach HFJ)
Warum OOP? OOP mit Java Vererbung Abstrakte Klassen und Interfaces
V3
Larry muss diesmal viel andern, da rotate
neue Paramter bekommen hat. Er mussalso auch alle Stellen andern, andenenrotate benutzt wird.
1 rotate(shapeNum , xPt , yPt) {
2 if (/*Form ist keine Amoebe */) {
3 // Rotiere um Box -Mittelpunkt
4 } else {
5 // Rotiere um xPt und yPt
6 }
7 }
Brad passt die rotate-Methode derAmoben-Klasse an. Fur denRotationspunkt erweitert er die Klasseum zwei Attribute. Ansonsten muss ernur Stellen verandern, an denen Amobenerzeugt werden, anderen Code muss ernicht anfassen.
1 class Amoeba {
2 int xPoint
3 int yPoint
4 rotate () {
5 //Drehe Amoebe um xPoint und yPoint
6 }
7 playSound () {
8 // Unveraendert
9 }
10 }
Warum OOP? OOP mit Java Vererbung Abstrakte Klassen und Interfaces
Der Trick mit der Vererbung
Verursacht Brads OOP Ansatz dopelten Code zwischen denMethoden?
Nicht umbedingt
Auslagern gemeinsamer Eigenschaften in ubergeordnete Klasse →Vererbung
Bild aus Head First Java - Second Edition
Warum OOP? OOP mit Java Vererbung Abstrakte Klassen und Interfaces
Noch ein Trick: Spezialisierung durch Uberschreiben
Nun wurden aber alle Formen gleich rotierenDie Amobe wurde das Verhalten der Elternklasse erben.Methoden konnen in Unterklassen geandert werden →Uberschreiben von Methoden
Bild aus Head First Java - Second Edition
Warum OOP? OOP mit Java Vererbung Abstrakte Klassen und Interfaces
OOP
Objekte = Verhalten (durch Methoden) + Daten (durch Attribute)
Klassen = Bauplane fur Objekte
Kapselung von Programmteilen
Einfacheres Andern von Programmen
Wiederverwendung von Programmteilen
Markus Reschke | Java Grundlagen 2 - OOP | 10Institut für Programmierung
und Reaktive Systeme
Warum OOP? OOP mit Java Vererbung Abstrakte Klassen und Interfaces
Klassen in Java
1 ZugriffsBeschraenker class KlassenName {
2 // Attribute
3 // Methoden
4 }
Eine Klasse mit public-Zugriffsbeschranker pro .java-Datei
Warum OOP? OOP mit Java Vererbung Abstrakte Klassen und Interfaces
Attribute in Java
Attribute beschreiben die Daten, die jedes Objekt speichert
Klasse gibt an, welche Attribute Objekte dieser Klasse haben
Jedes Objekt verfugt uber eine eigene Kopie dieser Attribute
Anderungen an den Attributen eines Objektes wirken sich nur aufdieses Objekt aus
Attribute sollen fast immer private sein.
Werden fast wie lokale Variablen definiert.
1 ZugriffsBeschraenker class KlassenName {
2 T attributsName;
3 T attributsName = Initialisierungswert.
4 // Methoden
5 }
Warum OOP? OOP mit Java Vererbung Abstrakte Klassen und Interfaces
Methoden
Methoden sind die Aktionen, die mit einem Objekt ausgefuhrtwerden konnen
Statische Methoden kennen wir schon
Unterschied zu statischen Methoden: Sie arbeiten auf einzelneObjekte
1 ZugriffsBeschraenker class KlassenName {
2 // Attribute
3 Zugriffsbeschraenker Rueckgabetyp name(T1 Paramter1 ,...) {
4 // Anweisungen
5 }
6 }
Warum OOP? OOP mit Java Vererbung Abstrakte Klassen und Interfaces
Zugriffsbeschranker
Zugriffsbeschranker erlauben es, Elemente von Klassen vor dem Zugriffvon außen versteckt. Dies erschwert unsachgemaße Verwendung vonObjekten und erleichtert Kapselung.
Beschranker Klasse Paket Unterklassen Rest
public Y Y Y Y
protected Y Y Y N
keine Angabe Y Y N N
private Y N N NNormalerweise reichen public und private.
Markus Reschke | Java Grundlagen 2 - OOP | 14Institut für Programmierung
und Reaktive Systeme
Warum OOP? OOP mit Java Vererbung Abstrakte Klassen und Interfaces
Beispiel: Counter
1 public class Counter {
2 private int count;
3
4 public void increase () {
5 count ++;
6 }
7
8 public int getCount () {
9 return count;
10 }
11
12 public void reset() {
13 count = 0;
14 }
15 }
Warum OOP? OOP mit Java Vererbung Abstrakte Klassen und Interfaces
Erzeugen von Objekten
Wir konnen nun selber Klassen erstellen, wie werden diese nunverwendet?
new erzeugt neue Objekte auf dem Heap.
Syntax: new Klassenname(Konstruktorparameter)
new gibt eine Referenz auf das neue Objekt zuruck
obj, Counter,
Stack
Counter {count, int, 1description, String,
}
Heap
String {...
}
1 Counter c = new Counter ();
Warum OOP? OOP mit Java Vererbung Abstrakte Klassen und Interfaces
Der . Operator
Wir konnen jetzt neue Objekte erzeugen.
Wie benutzt man nun ein Objekt?
Der .-Operator kann auf eine Referenz angewendet werden, um aufdie Attribute und Methoden des referenzierten Objekteszuzugreifen.
Voraussetzung ist, dass der Zugriff erlaubt ist (Beschranker)
Syntax: referenz.element
1 Counter c = new Counter ();
2 c.increase ();
3 c.increase ();
4 c.reset();
Markus Reschke | Java Grundlagen 2 - OOP | 17Institut für Programmierung
und Reaktive Systeme
Warum OOP? OOP mit Java Vererbung Abstrakte Klassen und Interfaces
Konstruktoren
Oft mussen beim Erzeugen von Objekten Attribute initialisiertwerden
Vom Benutzer der Klasse zu verlangen, dass er die Attribute selbernach dem Erzeugen setzt, kann zu Fehlern fuhren
Konstruktoren sind Methoden, die beim Erzeugen des Objektesaufgerufen werden.
Kein Ruckgabetyp, Gleicher Name wie Klasse
Falls keiner selber definiert: Default Konstruktor ohne ParameterKlassenname() wird automatisch erzeugt
Konstruktoren werden nicht vererbt
Warum OOP? OOP mit Java Vererbung Abstrakte Klassen und Interfaces
Beispiel: Counter1 public class Counter {
2 private int count;
3
4 public Counter () {
5 this (1);
6 }
7
8 public Counter(int start) {
9 count = start;
10 }
11
12 public void increase () {
13 count ++;
14 }
15
16 public int getCount () {
17 return count;
18 }
19
20 public void reset() {
21 count = 0;
22 }
23 }
Warum OOP? OOP mit Java Vererbung Abstrakte Klassen und Interfaces
Verdecken von Attributen und this
Lokale Variablen und Methodenparameter konnen Attributeverdecken
Zugriff auf lokale Variable anstatt aufs Attribut
this ist eine Referenz auf das aktuelle Objekt.
Kann benutzt werden, um trotz des Verdeckens auf das Attributzuzugreifen.
Markus Reschke | Java Grundlagen 2 - OOP | 20Institut für Programmierung
und Reaktive Systeme
Warum OOP? OOP mit Java Vererbung Abstrakte Klassen und Interfaces
Was Passiert?
1 public class Counter {
2 private int count = 100;
3
4 public void nichtVerdeckt () {
5 System.out.println(count);
6 }
7
8 public void verdeckt () {
9 int count = 0;
10 System.out.println(count);
11 }
12
13 public void verdecktParam(int count) {
14 System.out.println(count);
15 }
16
17 public void verdecktThis () {
18 int count = 0;
19 System.out.println(this.count);
20 }
21 }
Warum OOP? OOP mit Java Vererbung Abstrakte Klassen und Interfaces
static
static markiert Elemente von Klassen als statisch
Wird normalerweise hinter dem Zugriffsbeschranker angegeben
Fur statische Attribute existiert nur eine einzige Kopie, die von allenObjektinstanzen dieser Klasse geteilt wird.
Statische Methoden konnen ohne Objektinstanz genutzt werden,durfen aber auch nur auf statische Elemente der Klasse zugreifen
Nicht-statische Attribute existieren ja nur fur Objektinstanzen,statische Methodenaufrufe operieren auf keinem Objekt
Zugriff mit Klassenname.Element
Markus Reschke | Java Grundlagen 2 - OOP | 22Institut für Programmierung
und Reaktive Systeme
Warum OOP? OOP mit Java Vererbung Abstrakte Klassen und Interfaces
Was Passiert?
1 public class Statisch {
2 public int a = 0;
3 public static int b = 1;
4
5 public static void main(String [] args) {
6 Statisch n1 = new Statisch ();
7 n1.a = 1;
8 Statisch n2 = new Statisch ();
9 n2.a = 2;
10 System.out.println(n1.a);
11 System.out.println(n2.a);
12 n1.b = 5;
13 System.out.println(n1.b);
14 System.out.println(n2.b);
15 System.out.println(Statisch.b);
16 }
17 }
Warum OOP? OOP mit Java Vererbung Abstrakte Klassen und Interfaces
Uberladen von Methoden
Mehrere Methoden in einer Klasse konnen den selben Namen haben
Mussen sich in der Parameterliste unterscheiden (durch andereTypen, andere Anzahl von Parametern oder beidem)
Ruckgabetyp wird nicht zur Unterscheidung herangezogen
Auswahl der passenden Methode geschieht zur Kompilierzeit
Markus Reschke | Java Grundlagen 2 - OOP | 24Institut für Programmierung
und Reaktive Systeme
Warum OOP? OOP mit Java Vererbung Abstrakte Klassen und Interfaces
Was Passiert?
1 public class Overload {
2
3 public void foo(Object a) {
4 System.out.println("Das war ein Object");
5 }
6
7 public void foo(String a) {
8 System.out.println("Das war ein String");
9 }
10
11 public static void main(String [] args) {
12 Overload o = new Overload ();
13 Object obj = new String("Foobar");
14 o.foo(obj);
15 String str = new String("Foobar");
16 o.foo(str);
17 }
18
19 }
Warum OOP? OOP mit Java Vererbung Abstrakte Klassen und Interfaces
final
final vor Attributen und lokalen Variablen verhindert das Andern derer Werte
Fur Referenttypen heißt dies: Es kann nicht geandert werden, worauf dieReferenz zeigt.
Das referenzierte Objekt ansich ist jedoch noch veranderbar.
final vor Klassen: Von der Klasse kann nicht geerbt werden
final vor Methoden: Kein Uberschreiben moglich
1 import java.util .*;
2 public class Fin {
3 public static final List <String > l = new ArrayList <String >();
4 public static final int ANSWER = 42;
5
6 public static void main(String [] args) {
7 System.out.println(l);
8 //Geht nicht , da l final ist
9 //l = new ArrayList <String >();
10 //Das referenzierte Objekt selbst kann geaendert werden
11 l.add("Test");
12 System.out.println(l);
13 }
14 }
Warum OOP? OOP mit Java Vererbung Abstrakte Klassen und Interfaces
Vererbung in Java
Vererbung ermoglicht es, Klassen zu spezialisierenWiederverwendung vorhandener KlassenKindsklasse erhalt alle Attribute und Methoden der ElternklasseSyntax: class Kindsklasse extends Elternklasse ...
Objekte der Kindsklasse sind auch Objekte der ElternklasseKindsklasse kann Methoden andern (uberschreiben), Zugriff aufVersion der Elternklasse mit super
Jede Klasse hat genau eine direkte Elternklasse, ohne Angabe Object
Bild aus Head First Java - Second Edition
Warum OOP? OOP mit Java Vererbung Abstrakte Klassen und Interfaces
Ein schneller Counter1 public class Counter {
2 private int count;
3
4 public Counter(int start) {
5 this.count = start;
6 }
7
8 protected setCount(int count) {
9 this.count = count;
10 }
11
12 public void increase () {
13 count ++;
14 }
15
16 public int getCount () {
17 return count;
18 }
19
20 public void reset() {
21 count = 0;
22 }
23 }
Warum OOP? OOP mit Java Vererbung Abstrakte Klassen und Interfaces
Ein schneller Counter
Wichtig: Kindsklasse darf nicht auf private Elemente der Elternklasse zugreifen!
Wichtig: Konstruktoren werden nicht vererbt!
setCount ist protected, damit die Unterklasse, den Counter freier setzen kann
Alternativ: Mehrfache Benutzung von increase der Elternklasse
1 public class FastCounter extends Counter {
2
3 public FastCounter(int start) {
4 super(start);
5 }
6
7 public void increase () {
8 setCount(getCount () + 2);
9 }
10 }
1 public void increase () {
2 super.increase ();
3 super.increase ();
4 }
Warum OOP? OOP mit Java Vererbung Abstrakte Klassen und Interfaces
Polymorphie
Jedes Objekt einer Kindsklasse ist auch ein Objekt seiner Elternklassen.
1 Counter c = new FastCounter (0);
Java lost Methodenaufrufe auf Objekte zur Laufzeit auf
1 c.increase (); //Ruft increase von FastCounter auf , obwohl c eine
Counter -Referenz ist
2 System.out.println(c.getCount ()); // <- 2
Es wird die Methode des Typs des referenzierten Objektes aufgerufen,nicht die vom Typ der Referenz!Das Objekt selbst weiß, wie es was tun muss
Warum OOP? OOP mit Java Vererbung Abstrakte Klassen und Interfaces
Was passiert?
1 public class A {
2 public void say() {
3 System.out.println("Klasse A");
4 }
5 }
6
7 public class B extends A {
8 public void say() {
9 System.out.println("Klasse B");
10 }
11 }
12 ...
13 A a = new A();
14 a.say();
15 B b = new B();
16 b.say();
17 A b2 = new B();
18 b2.say();
Warum OOP? OOP mit Java Vererbung Abstrakte Klassen und Interfaces
== und Referenzen
== vergleicht fur Referenzdatentypen nur, ob beide Referenzen auf dasselbe Objekt zeigen.
1 Counter a = new Counter (0);
2 Counter b = new Counter (0);
3 System.out.println(a == b);
4 Counter c = a;
5 System.out.println(a == c);
Warum OOP? OOP mit Java Vererbung Abstrakte Klassen und Interfaces
equals
Alle Klassen erben von Object
Object hat Methode public boolean equals(Object o)
Ohne Uberschreiben wie ==
Kann in Unterklasse uberschrieben werden, um wertemaßig zuvergleichen
Da eine Referenz auf ein Object ubergeben wird, muss man beimuberschreiben auf zwei Sachen achten: null und den richtigen Typ
o intanceof Klasse gibt true zuruck, wenn o nicht null ist und einObjekt vom Typ der angegebenen Klasse ist
Warum OOP? OOP mit Java Vererbung Abstrakte Klassen und Interfaces
Counter equals()
1 public class Counter {
2 public boolean equals(Object o) {
3 if (!(o instanceof Counter)) {
4 return false; //o null oder falscher Typ
5 }
6 Counter c = (Counter) o;
7 return o.getCount () == getCount ();
8 }
9 }
10
11 Counter a = new Counter (0);
12 Counter b = new Counter (0);
13 System.out.println(a.equals(b));
14 Counter c = a;
15 System.out.println(a.equals(c));
Warum OOP? OOP mit Java Vererbung Abstrakte Klassen und Interfaces
Abstrakte Klassen
Klassen, von denen keine Objektinstanzen erzeugt werden konnen
Bauplane fur andere Klassen
Sind mit abstract markiert.
Konnen Methoden ohne Implementierung enthalten
Diese Methoden mussen auch mit abstract markiert werden.
Markus Reschke | Java Grundlagen 2 - OOP | 35Institut für Programmierung
und Reaktive Systeme
Warum OOP? OOP mit Java Vererbung Abstrakte Klassen und Interfaces
Ein abstrakter Counter
1 public abstract class IntCounter {
2 private int count;
3
4 public IntCounter(int start) {
5 this.count = start;
6 }
7
8 protected setCount(int count) {
9 this.count = count;
10 }
11
12 public abstract void increase ();
13
14 public int getCount () {
15 return count;
16 }
17
18 public void reset() {
19 count = 0;
20 }
21 }
Warum OOP? OOP mit Java Vererbung Abstrakte Klassen und Interfaces
Interfaces
Interfaces geben an, uber welche Methoden eine Klasse verfugt
Es wird jedoch keine Implementierung mitgegeben.
Eine Klasse kann beliebig viele Interfaces implementieren (imVergeich zum Erben)
Die Definition eines Interfaces wird mit interface eingeleitet.
Klassen implementieren Interfaces mit implements.
Interfaces sind Typen
Gegen Interfacetyp programmieren → Implementierungen einfachaustauchbar
1 ZugriffsBeschraenker interface KlassenName {
2 // Statische Konstanten (public , static , final sind implizit)
3 int ANSWER = 42;
4 // Abstrakte Methoden (abstract ,public sind implizit)
5 void foo();
6 }
Warum OOP? OOP mit Java Vererbung Abstrakte Klassen und Interfaces
Demo
Demo:UnaryCounter.java
ICounter.javaIntCounter.java
Main.java
Markus Reschke | Java Grundlagen 2 - OOP | 38Institut für Programmierung
und Reaktive Systeme
Warum OOP? OOP mit Java Vererbung Abstrakte Klassen und Interfaces
Uberblick und Ausblick
Warum OOP?
Klassen
Attribute
Methoden
static
Vererbung
Abstrakte Klassen und Interfaces
Morgen: Weitere Sprachfeatures von Java
Markus Reschke | Java Grundlagen 2 - OOP | 39Institut für Programmierung
und Reaktive Systeme