252-0027 einführungin dieprogrammierung 4.0 klassenundobjekte · 2018. 10. 24. · 252-0027...
TRANSCRIPT
-
252-0027Einführung in die Programmierung
4.0 Klassen und ObjekteThomas R. Gross
Department InformatikETH Zürich
1
-
Klassen und Objekte§ Objekt (“object”): Ein Gebilde das Zustand (“state”) und
Verhalten (“behavior”) verbindet.
§ Klasse ist die Vorlage (Mustervorlage, Schablone) die Objektebeschreibt§ Objekt wird gemäss Vorlage erschaffen
2
-
4.0 Klassen und Objekte§ 4.4 Attribute§ 4.5 Methoden§ 4.6 Konstruktoren
3
-
4.4 Attribute
Copyright (c) Pearson 2013. and Thomas Gross 2016All rights reserved.
4
-
Zustand eines Objekt: Attribute
5
-
7
-
9
-
Attribute § Attribute (“field”): Eine Variable innerhalb eines Objektes die
Teil des Objekt Zustandes ist. (Manchmal auch Objektattributgenannt.)
§ Beispiel:
public class Student {String name; // each Student object has a double notenDS; // name and grade avg. field
}
10
-
12
-
15
-
17
-
19
-
22
-
24
-
Klassen und Klienten§ Point.java ist (alleine) kein ausführbares Programm
§ Die Klasse kann von Klienten verwendet werden.
PointMain.java (Klient)public class PointMain {
public static void main(String[] args) {
Point p1 = new Point();p1.x = 7;p1.y = 2;
Point p2 = new Point();p2.x = 4;p2.y = 3;...
}}
Point.java (Klasse für Objekte)public class Point {
int x;int y;
}
28
-
new Operator§ Der new Operator initialisiert die Attribute mit “Null”
§ Für int Attribute: 0§ Für double Attribute: 0.0§ Für String Attribute: null
29
-
Klassen und Klienten - Zeitlupe§ Point.java ist (alleine) kein ausführbares Programm
§ Eine Klasse kann von Klienten verwendet werden.
PointMain.java (Klient)public class PointMain {
public static void main(String[] args) {
Point p1 = new Point();p1.x = 7;p1.y = 2;
Point p2 = new Point();p2.x = 4;p2.y = 3;...
}}
Point.java (Klasse für Objekte)public class Point {
int x;int y;
}
x 0 y 0
30
-
Klassen und Klienten - Zeitlupe§ Point.java ist (alleine) kein ausführbares Programm
§ Eine Klasse kann von Klienten verwendet werden.
PointMain.java (Klient)public class PointMain {
public static void main(String[] args) {
Point p1 = new Point();p1.x = 7;p1.y = 2;
Point p2 = new Point();p2.x = 4;p2.y = 3;...
}}
Point.java (Klasse für Objekte)public class Point {
int x;int y;
}
x 7 y 0
31
-
Klassen und Klienten - Zeitlupe§ Point.java ist (alleine) kein ausführbares Programm
§ Eine Klasse kann von Klienten verwendet werden.
PointMain.java (Klient)public class PointMain {
public static void main(String[] args) {
Point p1 = new Point();p1.x = 7;p1.y = 2;
Point p2 = new Point();p2.x = 4;p2.y = 3;...
}}
Point.java (Klasse für Objekte)public class Point {
int x;int y;
}
x 7 y 2
32
-
Klassen und Klienten - Zeitlupe§ Point.java ist (alleine) kein ausführbares Programm
§ Eine Klasse kann von Klienten verwendet werden.
PointMain.java (Klient)public class PointMain {
public static void main(String[] args) {
Point p1 = new Point();p1.x = 7;p1.y = 2;
Point p2 = new Point();p2.x = 4;p2.y = 3;...
}}
Point.java (Klasse für Objekte)public class Point {
int x;int y;
}
x 7 y 2
x 0 y 0
33
-
Klassen und Klienten - Zeitlupe§ Point.java ist (alleine) kein ausführbares Programm
§ Eine Klasse kann von Klienten verwendet werden.
PointMain.java (Klient)public class PointMain {
public static void main(String[] args) {
Point p1 = new Point();p1.x = 7;p1.y = 2;
Point p2 = new Point();p2.x = 4;p2.y = 3;...
}}
Point.java (Klasse für Objekte)public class Point {
int x;int y;
}
x 7 y 2
x 4 y 0
34
-
Klassen und Klienten - Zeitlupe§ Point.java ist (alleine) kein ausführbares Programm
§ Eine Klasse kann von Klienten verwendet werden.
PointMain.java (Klient)public class PointMain {
public static void main(String[] args) {
Point p1 = new Point();p1.x = 7;p1.y = 2;
Point p2 = new Point();p2.x = 4;p2.y = 3;...
}}
Point.java (Klasse für Objekte)public class Point {
int x;int y;
}
x 7 y 2
x 4 y 3
35
-
Klassen und Klienten§ Weitere Operationen …
PointMain.java (Klient)public class PointMain {
public static void main(String[] args) {
Point p1 = new Point();p1.x = 7;p1.y = 2;
Point p2 = new Point();p2.x = 4;p2.y = 3;p2 = p1;
}}
Point.java (Klasse für Objekte)public class Point {
int x;int y;
}
x 7 y 2
x 4 y 3
36
-
Reference Semantics§ Wir brauchen einen Weg, eine Reference
Variable zurückzusetzen (zu "nullifizieren")§ Besonderer Wert null (gut für alle Klassen)
Point p1 = new Point();p1.x = 7;p1.y = 2;...Point p2 = p1; // p2.x == 7, p2.y == 2...p2.x = 4; // p2.x == 4, p2.y == 2
// p1.x == 4, p2.y == 2
p2 = null; // only p1 refers to Point (4,2)38
-
Arrays mit Objekten§ null : Ein Wert der auf kein Objekt verweist
§ Die Elemente eines Arrays für Objekte werden mit null initialisiert.
String[] words = new String[5];DrawingPanel[] windows = new DrawingPanel[3];
index 0 1 2 3 4
value null null null null null
index 0 1 2
value null null null
words
windows40
-
Wofür null gut ist§ Speichern von null in einer Variablen oder einem Array
Element (eines durch eine Klasse definierten Typs)String s = null;words[2] = null;
§ Drucken des null Verweises (Referenz)System.out.println(s); // null
§ Prüfen ob eine Variable oder Array Element null istif (words[2] == null) { ...
41
-
Wofür null gut ist
§ Übergeben von null als ein Parameter einer MethodeSystem.out.println(null); // null
§ Zurückgeben von null von einer Methode (wird oft verwendet um einen Fehler anzuzeigen)return null;
42
-
null Reference§ null ist ein Wert (den eine Variable haben kann)
§ Variable mit Reference Semanticsint [] a = new int[10];a = null; // forget this array!
§ Hat eine Variable den Wert null so sprechen wir manchmalvon einer "null reference"
43
-
Null Reference Exception§ Dereferenzieren ("dereference"): Zugriff auf Attribute oder Methoden
eines Objektes in Dot Notation, z.B. s.method().
§ Es ist nicht erlaubt, null zu dereferenzieren (Laufzeitfehler, hat eineException zur Folge).
Point p1 = new Point();p1.x = 3; p1.y = 2;Point p2 = p1; // p2.x == 3, p2.y == 2p2 = null;System.out.println(“p2.x :” + p2.x);
§ null ist nicht irgendein Objekt, d.h. es gibt keine Methoden oder Daten44
-
Null Reference ExceptionString[] words = new String[5];System.out.println("word is: " + words[0]);words[0] = words[0].toUpperCase(); // ERROR
Output:word is: nullException in thread "main" java.lang.NullPointerException
at Example.main(Example.java:8)
§ Der Name java.lang.NullPointerException verrätetwas über die Implementierung von References
index 0 1 2 3 4value null null null null null
45
-
luege, lose, laufe …§ Sie können prüfen ob eine Referenz null ist bevor eine
Methode für ein Objekt aufgerufen wird. String[] words = new String[5];words[0] = "hello";words[2] = "goodbye"; // words[1], [3], [4] are null
for (int i = 0; i < words.length; i++) {if (words[i] != null) {
words[i] = words[i].toUpperCase();}
}index 0 1 2 3 4
value "HELLO" null "GOODBYE" null nullwords46
-
Arrays mit Objekten§ Arrays für Objekteelemente sind Arrays mit Verweisen auf
Exemplare§ Die Elemente eines Arrays für Objekte werden mit null initialisiert.
String[] words = new String[5];DrawingPanel[] windows = new DrawingPanel[3];
index 0 1 2 3 4
value null null null null null
index 0 1 2
value null null null
words
windows47
-
Initialisierung von Arrays1) Initialisierung des Arrays (jedes Element wird auf null gesetzt bei
Objekten, 0 bei Basistypen)2) Initialisierung der Elemente explizitString[] words = new String[4]; // phase 1for (int i = 0; i < words.length; i++) {coords[i] = "word" + i; // phase 2
}
Initialisierung in zwei Schritten (Phasen)
index 0 1 2 3
value "word0" "word1" "word2" "word3"words
48
-
Initialisierung von Arrays§ Zugriff in Dot-Notation für Attribute
Point[] ziel = new Point[3]; // phase 1for (int i = 0; i < ziel.length; i++) {// lese xpos, ypos aus Datei // phase 2Point p = new Point();p.x = xpos; p.y = ypos;ziel[i] = p;
} ziel
49
Index 0 1 2
Value null null null
-
Initialisierung von Arrays§ Zugriff in Dot-Notation für Attribute
Point[] ziel = new Point[3]; // phase 1for (int i = 0; i < ziel.length; i++) {// lese xpos, ypos aus Datei // phase 2Point p = new Point();p.x = xpos; p.y = ypos;ziel[i] = p;
} ziel
50
Index 0 1 2
Value
x 7y 2
x -9y 12
x 5y 123
-
Arrays mit Objektverweisen§ Zugriff in Dot-Notation für Attribute
Point[] ziel = new Point[3];
for (int j = 0; j < ziel.length; j++) {System.out.println("x pos = " + ziel[j].x +
" y pos = " + ziel[j].y );}
ziel
51
Index 0 1 2
Value
x 7y 2
x -9y 12
x 5y 123
-
53
-
Arrays mit Verweisen auf ArraysBeispielint square = console.nextInt();
int [] [] x = new int [square][square];
for (int i = 0; i < square; i++ ) {
x[i][i] = 1;
};
oder einfacher (für square == 3)
int [][] x = { {1, 0, 0}, {0, 1, 0}, {0, 0, 1} } ;54
-
Nicht nur für quadratische Matrizen
int [][] y = {{0, 1, 2, 9},{3, 4, 5, 10},{6, 7, 8, 11}};
System.out.println("#rows: " + y.length +
"\t #columns: " + y[0].length);
for (int i = 0; i< y.length; i++ ) {
System.out.print("row "+ i + " = \n[" + y[i][0]);
for (int j = 1; j< y[i].length; j++ ) {
System.out.print(", " + y[i][j]);
}
System.out.println("]");
} 55
-
Nicht nur für quadratische Matrizen
int [][] y = {{0, 1, 2, 9},{3, 4, 5, 10},{6, 7, 8, 11}};
System.out.println("#rows: " + y.length +
"\t #columns: " + y[0].length);
for (int i = 0; i< y.length; i++ ) {
System.out.print("row "+ i + " = \n[" + y[i][0]);
for (int j = 1; j< y[i].length; j++ ) {
System.out.print(", " + y[i][j]);
}
System.out.println("]");
} 56
System.out.println("row "+ i + " = \n" +
Arrays.toString(y[i]) );
-
int [][] y = 0, 1, 2, 9
3, 4, 5, 10
6, 7, 8, 11
#rows:3 #columns: 4
row 0 =
[0, 1, 2, 9]
row 1 =
[3, 4, 5, 10]
row 2 =
[6, 7, 8, 11] 57
-
4.5 Methoden
Copyright (c) Pearson 2013. and Thomas Gross 2016All rights reserved. 59
-
Ein Problem (Arbeitszeit berechnen)§ Die File hours.txt enthält die folgenden Daten:
123 Paula 12.5 8.1 7.6 3.2456 Erich 4.0 11.6 6.5 2.7 12789 Steffie 8.0 8.0 8.0 8.0 7.5
§ Wir wollen ein Programm schreiben das die Anzahl Stundenfür jede Person berechnet:
Paula (ID#123) worked 31.4 hours (7.85 hours/day)Erich (ID#456) worked 36.8 hours (7.36 hours/day)Steffie (ID#789) worked 39.5 hours (7.9 hours/day)60
-
Was für ein Objekt brauchen wir?§ Modellierung der "Person"§ Operationen mit Personen
61
-
Attribute§ Attribute können können einen beliebigen Typ haben
§ Basistypen§ Strings§ Arrays§ …
62
-
64
-
Beispiel Arbeitszeit§ Also in einer Klassepublic class HoursWorked {
public static void main (String[] args) {Scanner input = new Scanner(new File("data.txt"));Person [] staff = new Person[input.nextInt()];
for (int i=0; i < staff.length; i ++) { staff[i] = readData(input);
}//compute hours worked …
}65
-
Methoden beschreiben das Verhalten§ Beschreiben das Verhalten eines Objektes§ Verhalten – Zustandsänderungen oder Abfragen des
Zustandes
66
-
Redundanz im Klienten§ Unser Klientenprogramm möchte den Lohn für alle
Angestellten berechnen§ Gegeben ein Array staff von Person Objekten:
// compute total of salaries to payfor (int i = 0; i < staff.length; i ++) {
double sum = 0; for (int j = 0; j < staff[j].hours.length; j++) {
sum = sum + staff[i].hours[j];};salaries = sum * 20.00;
} // for i 67
-
Redundanz im Klienten§ Wenn wir diese Berechnung an mehreren Stellen durchführen
wollen, müssen wir den Code kopieren …§ Diese Art von Redundanz kann mit einer Methode verhindert werden
§ Methode computePay(Person p)public static double computePay(Person p) {
double sum = 0;for (int k = 0; k < p.hours.length; k++) {
sum = sum + p.hours[k];}return sum * 20;
} 69
-
Ohne Redundanz, Version 1§ main würde dann diese Methode aufrufen
// compute wages to be paid
double totalWages = 0.0;
for (int i = 0; i < staff.length; i ++) {
totalWages += computePay(staff[i]);
}
totalWages = totalWages + computePay(staff[i])70
-
Beispiel (Fortsetzung)public class HoursWorked {public static void main (String[] args) {
Scanner input = new Scanner(new File("data.txt"));Person [] staff = new Person[input.nextInt()];
for (int i=0; i < staff.length; i ++) { staff[i] = readData(input);
}double totalWages = 0.0;for (int i = 0; i < staff.length; i ++) {
totalWages += computePay(staff[i]);}
} //mainpublic static double computePay(Person p) {
double sum = 0;for (int k = 0; k < p.hours.length; k++) {
sum += p.hours[k];}return sum * 20;
} // computePay}
71
-
Probleme mit dieser Programmstruktur§ Methode computePay(…) ist Teil von HoursWorked (dem
Klienten)§ Jedes Programm das mit Person Objekten arbeitet müsste einecomputePay(…) Methode implementieren.
§ Objekte erlauben Wiederverwendung von Code – aber diesefindet nicht statt wenn jeder Klient den Code für die Gehaltsberechnung duplizieren muss.
72
-
Probleme mit dieser Programmstruktur§ Die Methode computePay(…) muss viele Einzelheiten
über die Implementation von Person Objekten wissenfor (int k = 0; k < p.hours.length; k++)
sum += p.hours[k];
}
§ Die Attribute von Person können sich aber ändern
73
-
Eine mögliche Änderung§ Der Array hours enthält die Anzahl Stunden, die eine
Person an einem Tag gearbeitet hat.
§ Was wenn wir zwischen Normalzeit und Überstundenunterscheiden wollen ?§ Ersten 8 Stunden/Tag sind Normalzeit, sFr 20.00 pro Stunde§ Über 8 Stunden gilt als Überstunde, 25% Zuschlag
§ Wir müssen Person Objekte anpassen und die MethodencomputePay(…) in allen Klienten anpassen
74
-
Person mit Überstunden Attributepublic class Person {
String name;
int id;
double [] hours;
double [] overtime;
}
§ Viele andere Attribute für richtige Personendaten …
75
-
computePaymit Überstundenpublic static double computePay(Person p) {
double sumStd = 0.0;double sumOvt = 0.0;for (int i = 0; i < p.hours.length; i++) {
sumStd += p.hours[i];}for (int i = 0; i < p.overtime.length; i++) {
sumOvt += p.overtime[i];}return sumStd * 20 + sumOvt*25;
}
76
-
Probleme mit dieser Programmstruktur
§ Wir wollen Klassen entwickeln die (innerhalb einesbestimmten Rahmens) von den Klienten unabhängig(weiter)entwickelt werden können.
§ Wir wollen Klienten entwickeln die von der Implementation der Klassen (die sie verwenden) unabhängig sind.
77
-
Probleme mit dieser Programmstruktur
§ Im Klienten ist überhaupt nicht ersichtlich dasscomputePay(…) eine Methode für Person Objekte istEs wird ein Person Objekt als Parameter übergebenfor (int i = 0; i < staff.length; i ++) {
totalWages += computePay(staff[i]);}
§ Person Objekte sind Parameter, aber kein weiterer Bezugzur Person Klasse
79
-
Probleme mit dieser Programmstruktur
§ Klassen sollten Zustand und Verhalten kombinieren.§ Berechnung des Gehaltes computePay ist ein Verhalten das eng
mit den Daten eines Person Objektes verbunden ist.§ Diese Methode gehört daher in jedes Person Objekt.§ Dann kann diese Methode in Dot Notation aufgerufen werdentotalWages += staff[i].computePay();
80
-
82
-
Beispielepublic class SomeClass {
public void hello(String name) {System.out.println("HELLO " + name);
}}
public class Person {// attributes omitted
public void present() {System.out.println(”Mit dabei ...”);
}}// usage example on next slide
83
-
Beispiel, Fortsetzungpublic class HoursWorked {
public static void main(String[] args) {Scanner input = new Scanner(new File("data.txt"));Person [] staff = new Person[input.nextInt()];
for (int i=0; i < staff.length; i ++) { staff[i] = readData(input);
}// various updates, persons are hired/leave
// check if entries are still in usefor (int i=0; i < staff.length; i ++) {
staff[i].present();}
}} 84
-
Methoden für Objekt(exemplar)epublic class Person {
String name;int id;double [] hours; double [] overtime;// Computes wages, 25% overtime supplementpublic double computePay() {
…}
}
§ Die computePay Method hat nicht mehr einen Person p Parameter. § Wie "weiss" die Methode wieviele Std. eine Person gearbeitet hat?
§ Wie erhält die Methode Zugang zu Daten in hours und overtime?85
-
§ Jedes Person Objekt hat seine eigene Kopie der computePayMethode, die mit dem Zustand dieses Objektes arbeitet:
Person p1 = new Person();// read data
Person p2 = new Person();// read data
p1.computePay();p2.computePay();
Person Objekte mit Methoden
86
-
Person p1 = new Person();// read data
Person p2 = new Person();// read data
p1.computePay();p2.computePay(); public void computePay() {
// this code can see p1's data}
hours[0] 12.5 hours[1] 8.1 hours[2] 7.6
p2
p1
public void computePay() {// this code can see p2's data
}
hours[0] 4.0 hours[1] 11.6 hours[2] 6.5
87
-
Person Objekte mit Methode computePaypublic class Person {
String name;int id;double [] hours; double [] overtime;
// Computes wages, 25% overtime supplementpublic double computePay() {double sumStd = 0;double sumOvt = 0;for (int i=0; i