252-0027 Einführung in die Programmierung I 7.0 Arbeiten mit Objekten und Klassen Thomas R. Gross Department Informatik ETH Zürich Copyright (c) Pearson 2013. and Thomas Gross 2016 All rights reserved.
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; x y // first stmt z 3
Variable eines Basistyps, Methode public static void somefct() { int x = 0; int y = 0; int z = 0; x y 0 0 // first stmt z 0 4
Leider falsch. Lokale Variable müssen explizit initialisiert werden, siehe letzte Slides. 5
Variable eines Basistyps, Instanzmethode void somefct() { int x = 1; int y = x + 1; int z = 0; x y // first stmt z 6
Variable eines Basistyps, Instanzmethode void somefct() { int x = 1; int y = x + 1; int z = 0; // first stmt x y z 1 2 0 7
Variable eines Basistyps, Attribute public class SomeClass { int x = 1; int y = x + 1; int z; x y void somefct() { // first stmt z 8
public class SomeClass { int x = 1; int y = x + 1; int z; public class OtherClass { void otherfct() { SomeClass s = new SomeClass(); // first stmt 9 x y z
public class SomeClass { OtherClass.java SomeClass.java int x = 1; int y = x + 1; int z; public class OtherClass { void otherfct() { SomeClass s = new SomeClass(); // first stmt 10 x y z
public class SomeClass { OtherClass.java SomeClass.java int x = 1; int y = x + 1; int z; public class OtherClass { void otherfct() { x 1 y 2 z 0 SomeClass s = new SomeClass(); // z set to 0 even w/o initialization 11
OtherClass.java SomeClass.java class SomeClass { int x; class OtherClass { public static void main (String[] args) { SomeClass x = new SomeClass(); System.out.println(x.x); // poor naming x 12
Variable eines Referenztypes ( reference variable ) public static void somefct() { SomeClass c; c // first stmt System.out.println(c); Class2d.java:8: variable c might not have been initialized System.out.println(c) 1 error ^ 14
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
17
Variable eines Referenztypes ( reference variable ) public static void somefct() { int [] x; x // first stmt System.out.println(x); Class2d.java:8: variable x might not have been initialized System.out.println(x) 1 error ^ 20
Variable eines Referenztypes ( reference variable ) public static void somefct() { int [] x = new int[3]; x // first stmt Index 0 1 2 Element 0 0 0 21
Variable eines Referenztypes ( reference variable ) public static void somefct() { int [] x = {2, 5, 8; x // first stmt Index 0 1 2 Element 2 5 6 22
Variable eines Referenztypes ( reference variable ) public static void somefct() { String [] s = null; s // first stmt 23
Variable eines Referenztypes ( reference variable ) public static void somefct() { String [] s = { a, b, c ; s // first stmt Index 0 1 2 Element a b c 24
Variable eines Referenztypes ( reference variable ) public static void somefct() { String [] s = new String[3] s // first stmt Index 0 1 2 Element null null null 25
Attribute einer Klasse public class SomeClass { int i; int [] ia; OtherClass o; i ia o 26
Variable eines Referenztypes ( reference variable ) public static void somefct() { SomeClass c = new SomeClass(); c // first stmt i 0 ia null o null 28
Variable eines Referenztypes ( reference variable ) public static void somefct() { SomeClass [] ca = new SomeClass[3]; ca // first stmt Index 0 1 2 Element null null null 29
31
Variable eines Referenztypes ( reference variable ) public static void somefct() { SomeClass [] ca = new SomeClass[3]; ca for (int i=0; i<3; i++){ ca[i] = new SomeClass(); Index 0 1 2 Element ca[i].ia = new int[3]; i ia 0 i ia 0 i ia 0 32 o null o null o 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 32
34
Attribute einer Klasse public class SomeClass { int i; int [] ia; SomeClass o; i ia o 35
39
41
Variable eines Referenztypes ( reference variable ) public static void somefct() { SomeClass c = new SomeClass(); SomeClass d = null; c d d = c; d.i = 1; c = null; d = null; i ia o 1 null null 42
Variable eines Referenztypes ( reference variable ) public static void somefct() { SomeClass c = new SomeClass(); SomeClass d = new SomeClass(); c d i 0 i 0 ia null ia null 43 o null o null
Variable eines Referenztypes ( reference variable ) public static void somefct() { SomeClass c = new SomeClass(); SomeClass d = new SomeClass(); c d c.o = d; i 0 i 0 ia null ia null o o null 44
Variable eines Referenztypes ( reference variable ) public static void somefct() { SomeClass c = new SomeClass(); SomeClass d = new SomeClass(); c d c.o = d; i 0 i 0 ia null ia null Wie kann ich d.i auf 1 setzen? 2 Möglichkeiten 45 o o null
46
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; JederKnoten derlistespeichert: Den Wert einer ganzen (int) Zahl Einen Verweis auf einen anderen Listenknoten 42-3 17 9 null ListNodes können zu einerkette verbunden ( linked ) werden um eine Menge oder Liste von Werten zu speichern.
Verknüpfte Knoten -- Uebungsproblem 1 Welche Folge von Anweisungen verändert dieses Bild: list 10 20 in dieses? list 10 20 30 list.next.next = new ListNode(30);
Verknüpfte Knoten -- Uebungsproblem 2 Welche Folge von Anweisungen verändert dieses Bild: list 10 20 in dieses? list 30 10 20 list = new ListNode(30, list);
Verknüpfte Knoten -- Uebungsproblem 3 Welche Folge von Anweisungen verändert dieses Bild: list1 10 20 in dieses? list2 30 40 list1 10 30 20 list2 40
rest = list2.next; list2.next = list1.next; list1.next = list2; list2 = rest; 64
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 1 a 10 2 1 zeigt 2 20
Referenzen verändern Wenn das Programm sagt: a 10 20 a.next = b.next; b 30 40 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."
Verknüpfte Knoten -- Uebungsproblem 4 Welche Folge von Anweisungen verändert dieses Bild: list 10... 990 in dieses? list 10... 990 data 1000 next
Frage über verknüpfte Knoten Nehmen wir an wir haben eine lange Kette von Knoten: list 10 20... 990 Wir wissen nicht wie lang die Kette ist. Wie könnten wir die Werte in allen Knoten ausgeben?
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. list 10 20... 990
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. list 10 20... 990 Wie wissen wir ob noch Knoten auszugeben sind? Wir haben einen Verweis auf einen Knoten Nach der Ausgabe des letzten Knotens ist next null.
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. list 10 20... Wie können wir uns durch die Liste arbeiten? 990 list = list.next; // is this a good idea?
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) list 10 20... 990
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; list 10 20... 990 current
Eine weitere Referenz: current ListNode current = list; list 10 20... 990 current Was passiert wenn wir jetzt diese Anweisung ausführen: current = current.next;
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 list 10 20 Das Verändern von current hat keinen Einfluss auf die Liste.... 990
Eine Klasse LinkedIntList ListNodes sollen nichtvon Klienten direktverändert werden. Also entwickeln wir eine Klasse die die Knoten versteckt: LinkedIntList. LinkedIntList front ListNode ListNode ListNode 42-3 17 element 0 element 1 element 2
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 LinkedIntList front add(value) add(index, value) indexof(value) remove(index) size() tostring() ListNode ListNode ListNode 42-3 17 element 0 element 1 element 2
LinkedIntList Klasse v1 public class LinkedIntList { private ListNode front; public LinkedIntList() { front = null; LinkedIntList front = // methods go here
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 = 42-3 17 element 0 element 1 element 2
Ein Element n eine leere Liste hinzufügen Bevor 20 hinzugefügt wird: Danach: front = front = 20 element 0 Wir müssen einen Knoten erstellen und an die Liste anhängen.
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...
An eine nicht-leere Liste anhängen Bevor 20 am Ende hinzugefügt wird : front = 42-3 element 0 element 1 Danach: front = 42-3 20 element 0 element 1 element 2
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 = 42-3 element 0 element 1
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 = 42-3 element 0 element 1 Wie durchlaufen wir eine Liste?
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 = 42-3 element 0 element 1 current = Wie durchlaufen wir eine Liste?
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 = 42-3 element 0 element 1 current = Wie durchlaufen wir eine Liste? Was für einen Typ muss current haben?
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 = 42-3 element 0 element 1 current = Wie durchlaufen wir eine Liste? Was für einen Typ muss current haben? ListNode
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 = 42-3 element 0 element 1 Worauf sollte current verweisen wenn wir 20 am Ende einfügen wollen? Welcher Loop Test lässt uns an dieser Stelle anhalten?
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);