67
252-0027 Einführung in die Programmierung 4.0 Klassen und Objekte Thomas R. Gross Department Informatik ETH Zürich 1

252-0027 Einführungin dieProgrammierung 4.0 KlassenundObjekte · 2018. 10. 24. · 252-0027 Einführungin dieProgrammierung 4.0 KlassenundObjekte Thomas R. Gross Department Informatik

  • Upload
    others

  • View
    3

  • Download
    0

Embed Size (px)

Citation preview

  • 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