252-0027
Einführung in die Programmierung I
7.0 Arbeiten mit Objekten und Klassen
Thomas R. Gross
Uebersicht
6.9999 Review
7.0 Listen als Beispiel
Copyright (c) Pearson 2013 and Thomas Gross 2016.
All rights reserved. 2
Variable eines Basistyps, Methode
public static void someFct() { int x = 0;
int y = 0;
int z = 0;
// first stmt
x
y
z
Variable eines Basistyps, Methode
public static void someFct() { int x = 0;
int y = 0;
int z = 0;
// first stmt
}
4
x y z
0
0
0
Variable eines Basistyps, Instanzmethode
void someFct() { int x = 1;
int y = x + 1;
int z = 0;
// first stmt
}
6
x
y
z
Variable eines Basistyps, Instanzmethode
void someFct() { int x = 1;
int y = x + 1;
int z = 0;
// first stmt
x y z
1
2
0
Variable eines Basistyps, Attribute
public class SomeClass { int x = 1;
int y = x + 1;
int z;
void someFct() { // first stmt }
} 8
x
y
z
public class SomeClass { int x = 1;
int y = x + 1;
int z;
}
public class OtherClass { void otherFct() {
SomeClass s = new SomeClass();
// first stmt
x
y
z
public class SomeClass { int x = 1;
int y = x + 1;
int z;
}
public class OtherClass { void otherFct() {
SomeClass s = new SomeClass();
// first stmt }
} 10
x y z
OtherClass.javaSomeClass.java
public class SomeClass { int x = 1;
int y = x + 1;
int z;
}
public class OtherClass { void otherFct() {
SomeClass s = new SomeClass();
// z set to 0 even w/o initialization
x y z
ass.javaSomeClass.java
1
2
0
class SomeClass { int x;
}
class OtherClass {
public static void main (String[] args) { SomeClass x = new SomeClass();
System.out.println(x.x);
} // poor naming … }
12
x
OtherClass.javaSomeClass.java
Variable eines Referenztypes
(“reference variable”) public static void someFct() {SomeClass c;
// first stmt
System.out.println(c);
}
Class2d.java:8: variable c might not have been initialized
c
Variable eines Referenztypes
(“reference variable”)§ Alle Variablen müssen in einer Methode initialisiert werden
§ Gilt für Variable die Referenzen (Verweise) auf Objekte speichern
§ Gilt für auch für Arrays
§ Verwenden auch Referenzvariable
§ Sonst gibt es eine Compiler Error Message
§ Es muss für den Compiler klar sein dass eine Zuweisung stattfand
§ Wenn möglich in Definition initialisieren
15
Variable eines Referenztypes
(“reference variable”) public static void someFct() {int [] x;
// first stmt
System.out.println(x);
}
Class2d.java:8: variable x might not have been initialized System.out.println(x)
^
1 error 20
x
Variable eines Referenztypes
(“reference variable”) public static void someFct() {int [] x = new int[3];
// first stmt
}
x
Index 0 1 2
Element 0 0 0
Variable eines Referenztypes
(“reference variable”) public static void someFct() {int [] x = {2, 5, 8};
// first stmt
}
22
x
Index 0 1 2
Element 2 5 6
Variable eines Referenztypes
(“reference variable”) public static void someFct() {String [] s = null;
// first stmt
}
s
Variable eines Referenztypes
(“reference variable”) public static void someFct() {String [] s = {“a”, “b”, “c”};
// first stmt
}
24
s
Index 0 1 2
Element “a” “b” “c”
Variable eines Referenztypes
(“reference variable”) public static void someFct() {String [] s = new String[3]
// first stmt
}
s
Index 0 1 2
Element null null null
Attribute einer Klasse
public class SomeClass { int i;
int [] ia;
OtherClass o;
}
26
i ia
o
Variable eines Referenztypes
(“reference variable”) public static void someFct() {SomeClass c = new SomeClass();
// first stmt
}
c
i ia
0
null
Variable eines Referenztypes
(“reference variable”) public static void someFct() {SomeClass [] ca = new SomeClass[3];
// first stmt
}
29
ca
Index 0 1 2
Element null null null
Variable eines Referenztypes
(“reference variable”) public static void someFct() {SomeClass [] ca = new SomeClass[3];
for (int i=0; i<3; i++){
ca[i] = new SomeClass();
ca[i].ia = new int[3];
}
} 32
ca
32
Index 0 1 2
Element
i
ia
o
0
null
i
ia
o
0
null
i
ia
o
0
null
Index 0 1 2
Element 0 0 0
Index 0 1 2
Element 0 0 0
Index 0 1 2
Element 0 0 0
Attribute einer Klasse
public class SomeClass { int i;
int [] ia;
SomeClass o;
}
35
i ia
o
41
Variable eines Referenztypes
(“reference variable”) public static void someFct() {SomeClass c = new SomeClass();
SomeClass d = null;
d = c;
d.i = 1;
c = null;
c
i ia
1 null
d
Variable eines Referenztypes
(“reference variable”) public static void someFct() {SomeClass c = new SomeClass();
SomeClass d = new SomeClass();
} 43
c
i ia
o
0 null null
d
i ia
o
0 null null
Variable eines Referenztypes
(“reference variable”) public static void someFct() {SomeClass c = new SomeClass();
SomeClass d = new SomeClass();
c.o = d;
}
c
i ia
0 null
d
i ia
0 null
Variable eines Referenztypes
(“reference variable”) public static void someFct() {SomeClass c = new SomeClass();
SomeClass d = new SomeClass();
c.o = d;
}
Wie kann ich
d.iauf 1 setzen?
2 Möglichkeiten …
45c
i ia
o
0 null
d
i ia
o
0 null null
Referenzen und Objekte
§ In Java, für Objekte und Arrays gelten die ”reference
semantics” Regeln.
Eine Klasse für Knoten einer Liste
public class ListNode { int data;
ListNode next;
}
§ Jeder Knoten der Liste speichert:
§ Den Wert einer ganzen (int) Zahl
§ Einen Verweis auf einen anderen Listenknoten
data next data next data next data next
Verknüpfte Knoten -- Uebungsproblem 1
Welche Folge von Anweisungen verändert dieses Bild:
in dieses?
list.next.next = new ListNode(30);
data next 10
data next list 20
data next 10
data next
list 20 data next
30
Verknüpfte Knoten -- Uebungsproblem 2
Welche Folge von Anweisungen verändert dieses Bild:
in dieses?
data next 10
data next list 20
data next 30
data next
list 10 data next
20
Verknüpfte Knoten -- Uebungsproblem 3
Welche Folge von Anweisungen verändert dieses Bild:
in dieses?
data next 10
data next list1 20
data next 30
data next list2 40
data next 10
data next list1 30
data next list2 40
data next 20
rest = list2.next;
list2.next = list1.next;
list1.next = list2;
list2 = rest;
Referenzen vs. Objekten
Variable = Wert ;
Eine Variable (links von = ) ist ein Zeiger ("Referenzvariable")
Ein Wert (rechts von = ) ist ein Objekt (ein Rechteck,; worauf der Zeiger zeigt)
§ Für die Liste rechts:
§ a.next = value;
heisst anpassen worauf zeigt
§ variable = a.next;
heisst die variable setzen so dass sie auf zeigt
data next
a 10 data next
1 20
2
1
2
Referenzen verändern
§ Wenn das Programm sagt:
§ a.next = b.next;
§ dann heisst das:
§ ”Lasse die Variable a.next auf den selben Wert (Objekt) zeigen wie b.next."
§ Oder, ”Lasse a.next auf den selben Ort wie b.next zeigen."
data next
a 10 data next
20 data next
b 30 data next
40
Verknüpfte Knoten -- Uebungsproblem 4
Welche Folge von Anweisungen verändert dieses Bild:
in dieses?
data next 10
data next list 990
...
data next 10
data next list 990
...
data next 1000
Frage über verknüpfte Knoten
§ Nehmen wir an wir haben eine lange Kette von Knoten:
§ Wir wissen nicht wie lang die Kette ist.
data next 10
data next list 990
...
data next 20
Algorithmus Pseudocode
§ Fangen wir am Anfang der Liste an, front ist der 1. Knoten
§ while (es gibt noch Knoten auszugeben):
§ Gebe den data Wert des Knotens aus
§ Gehe weiter zum nächsten Knoten via das next Attribut.
data next 10
data next list 990
...
data next 20
Algorithmus Pseudocode
§ Fangen wir am Anfang der Liste an, front ist der 1. Knoten
§ while (es gibt noch Knoten auszugeben):
§ Gebe den data Wert des Knotens aus
§ Gehe weiter zum nächsten Knoten via das next Attribut.
§ Wie wissen wir ob noch Knoten auszugeben sind?
data next 10
data next list 990
...
data next 20
Algorithmus Pseudocode
§ Fangen wir am Anfang der Liste an, front ist der 1. Knoten
§ while (es gibt noch Knoten auszugeben):
§ Gebe den data Wert des Knotens aus
§ Gehe weiter zum nächsten Knoten via das next Attribut.
§ Wie können wir uns durch die Liste arbeiten ?
list = list.next; // is this a good idea?
data next 10
data next list 990
...
data next 20
Abarbeiten einer Liste?
§ Ein (schlechter) Weg jeden Wert in der Liste auszugeben :
while (list != null) {
System.out.println(list.data);
list = list.next; // move to next node }
§ Was ist das Problem?
§ (Wir verlieren die Liste während wir sie ausgeben)
Eine weitere Referenz: current
§ Wir wollen list nicht verändern. Wir deklarieren eine andere Variable und ändern diese.
§ Eine ListNode Variable ist nicht ein ListNode Objekt
§ … sondern eine Referenz (Verweis) auf ein Objekt
ListNode current = list;
data next 10
data next list 990
...
data next 20
current
Eine weitere Referenz: current
ListNode current = list;
§ Was passiert wenn wir jetzt diese Anweisung ausführen:
current = current.next;
data next 10
data next list 990
...
data next 20
current
Korrektes Durchlaufen einer Liste
§ Der korrekte Weg jeden Wert der Liste auszugeben:
ListNode current = list;
while (current != null) {
System.out.println(current.data);
current = current.next; // move to next node }
§ Das Verändern von current hat keinen Einfluss auf die Liste.
data next 10
data next list 990
...
data next 20
Eine Klasse LinkedIntList
§ ListNode s sollen nicht von Klienten direkt verändert werden.
§ Also entwickeln wir eine Klasse die die Knoten versteckt:
LinkedIntList .
front LinkedIntList
ListNode ListNode ListNode
data next 42
data next -3
data next
§ Hat die Methoden:
§ add, add, get, indexOf, remove, size, toString
§ Die Liste ist als Kette von Knoten intern implementiert
§ Das LinkedIntList Objekt enthält eine Referenz auf das erste Element im front
§ null im next Attribut signalisiert Ende der Liste
§ Hat front den Wert null so ist die Liste leer
front add(value)
add(index, value) indexOf(value) remove(index) size()
toString() LinkedIntList
ListNode ListNode ListNode
data next 42
data next -3
data next 17
element 0 element 1 element 2
LinkedIntList Klasse v1
public class LinkedIntList { private ListNode front;
public LinkedIntList() { front = null;
}
// methods go here
front = LinkedIntList
Die add Methode
// Adds the given value to the end of the list.
public void add(int value) { ...
}
§ Wie wollen wir einen neuen Knoten am Ende hinzufügen?
§ Sind die Werte in der Liste vor diesem Schritt wichtig?
front =
data next 42
data next -3
data next 17
element 0 element 1 element 2
Ein Element n eine leere Liste hinzufügen
§ Bevor 20 hinzugefügt wird: Danach:
front = front =
data next 20
element 0
Die add Methode, 1. Versuch
// Adds the given value to the end of the list.
public void add(int value) { if (front == null) {
// adding to an empty list front = new ListNode(value);
} else {
// adding to the end of an existing list
...
} }
§ Bevor 20 am Ende hinzugefügt wird :
front =
data next 42
data next -3
front =
data next 42
data next 20
element 0 element 1
An eine nicht-leere Liste anhängen
data next -3
data next -3
Vorsicht an der Kante!
§ Um ein Element zur Liste hinzuzufügen (oder zu von der Liste zu entfernen) müssen wir das next Attribut des vorherigen Knotens modifizieren.
front =
data next 42
element 0 element 1
data next -3
Vorsicht an der Kante!
§ Um ein Element zur Liste hinzuzufügen (oder zu von der Liste zu entfernen) müssen wir das next Attribut des vorherigen Knotens modifizieren.
front =
data next 42
element 0 element 1
data next -3
Vorsicht an der Kante!
§ Um ein Element zur Liste hinzuzufügen (oder zu von der Liste zu entfernen) müssen wir das next Attribut des vorherigen Knotens modifizieren.
§ Wie durchlaufen wir eine Liste?
front =
data next 42
element 0 element 1 current =
data next -3
Vorsicht an der Kante!
§ Um ein Element zur Liste hinzuzufügen (oder zu von der Liste zu entfernen) müssen wir das next Attribut des vorherigen Knotens modifizieren.
front =
data next 42
element 0 element 1 current =
data next -3
Vorsicht an der Kante!
§ Um ein Element zur Liste hinzuzufügen (oder zu von der Liste zu entfernen) müssen wir das next Attribut des vorherigen Knotens modifizieren.
§ Wie durchlaufen wir eine Liste?
§ Was für einen Typ muss current haben? ListNode
front =
data next 42
element 0 element 1 current =
data next -3
Vorsicht an der Kante!
§ Um ein Element zur Liste hinzuzufügen (oder zu von der Liste zu entfernen) müssen wir das next Attribut des vorherigen Knotens modifizieren.
§ Worauf sollte verweisen wenn wir 20 am Ende einfügen
front =
data next 42
element 0 element 1
Die add Methode
// Adds the given value to the end of the list.
public void add(int value) { if (front == null) {
// adding to an empty list front = new ListNode(value);
} else {
// adding to the end of an existing list ListNode current = front;
while (current.next != null) { current = current.next;
}
current.next = new ListNode(value);
} }