Docsity
Docsity

Prüfungen vorbereiten
Prüfungen vorbereiten

Besser lernen dank der zahlreichen Ressourcen auf Docsity


Download-Punkte bekommen.
Download-Punkte bekommen.

Heimse Punkte ein, indem du anderen Studierenden hilfst oder erwirb Punkte mit einem Premium-Abo


Leitfäden und Tipps
Leitfäden und Tipps

Kapitel 17: Objektorientierung in Java, Leitfäden, Projektarbeiten und Recherchen von Syntax

– Methoden: Parameter und Rückgabewert haben Typ. • Unwichtige Unterschiede: Syntaxdetails, z.B. new. • Wesentliche Unterschiede: Das Vererbungskonzept! 17.2.2 ...

Art: Leitfäden, Projektarbeiten und Recherchen

2021/2022

Hochgeladen am 09.08.2022

Melissa_Lehmann
Melissa_Lehmann 🇩🇪

4.5

(26)

45 dokumente

1 / 41

Toggle sidebar

Diese Seite wird in der Vorschau nicht angezeigt

Lass dir nichts Wichtiges entgehen!

bg1
Kapitel 17: Objektorientierung in Java
Vorlesung Programmierung
Holger Karl
Wintersemester 2018/2018
Inhaltsverzeichnis
Inhaltsverzeichnis 1
Abbildungsverzeichnis 2
Liste von Definitionen u.ä. 2
17.1 Überblick ............................... 3
17.2 Klassen ................................ 3
17.3 Methoden .............................. 7
17.4 Einfachvererbung .......................... 20
17.5 Mehrfachvererbung und Ersatz dafür ............... 30
17.6 Zusammenfassung, Einordnung .................. 40
1
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17
pf18
pf19
pf1a
pf1b
pf1c
pf1d
pf1e
pf1f
pf20
pf21
pf22
pf23
pf24
pf25
pf26
pf27
pf28
pf29

Unvollständige Textvorschau

Nur auf Docsity: Lade Kapitel 17: Objektorientierung in Java und mehr Leitfäden, Projektarbeiten und Recherchen als PDF für Syntax herunter!

Kapitel 17: Objektorientierung in Java

Vorlesung Programmierung

Holger Karl

Wintersemester 2018/

Inhaltsverzeichnis

Inhaltsverzeichnis 1

Abbildungsverzeichnis 2

Liste von Definitionen u.ä. 2 17.1 Überblick............................... 3 17.2 Klassen................................ 3 17.3 Methoden.............................. 7 17.4 Einfachvererbung.......................... 20 17.5 Mehrfachvererbung und Ersatz dafür............... 30 17.6 Zusammenfassung, Einordnung.................. 40

Abbildungsverzeichnis

  • 17.1 Methodenaufruf mit Referenzparameter: Vor Zuweisung in f
  • 17.2 Methodenaufruf mit Referenzparameter: Nach Zuweisung in f
  • 17.3 Methodenaufruf mit Referenzparameter: Vor Zuweisung in g
  • 17.4 Methodenaufruf mit Referenzparameter: Nach Zuweisung in g
  • 17.5 Nach Rückkehr aus g
  • 17.6 Entwickler sind mit Mehrfachvererbung überfordert
  • 17.7 UML-Diagramm einer einfachen Tierfarm
  • 17.8 Unterschied zwischen abstract class und interface
  • 17.9 defaults in interfaces
    • 17.1 Definition (Signatur einer Methode) Liste von Definitionen u.ä.
    • 17.2 Definition (Sichtbarkeit einer Variablen in Java)
    • 17.3 Definition (Lebensdauer einer Variable in Java)

4 Liste von Definitionen u.ä.

1 class Klassenname { 2 Variablendeklaration1; 3 Variablendeklaration2; 4 Variablendeklaration3; 5 6 Methodendeklaration 7 Methodendeklaration 8 Methodendeklaration 9 }

17.2.3 Klassendeklaration: Beispiel Ellipse

Zunächst eine Klasse ohne Methode

  • Im Block der Klasse die Deklarationen der Daten-Attribute eines Ellipse- Objektes

1 class Ellipse { 2 // Daten deklarieren: 3 double x, y; 4 double achse1, achse2; 5 }

17.2.4 Ellipsenobjekt erzeugen

Zwei Aspekte: Deklaration und Erzeugung

Deklaration Wir deklarieren eine Variable vom Typ Ellipse

  • Analogie: eine leere Schachtel anlegen
  • Syntax entspricht Deklaration von int, String, etc. – Ellipse ist ein neuer Typ

1 // Variable deklarieren; es gibt noch kein Objekt! 2 Ellipse e;

17.2.5 Ellipsenobjekt erzeugen

Zwei Aspekte: Deklaration und Erzeugung

17.2. Klassen 5

Erzeugung

  • Wir erzeugen ein Objekt vom Typ Ellipse - Schlüsselwort: new * Mit Aufruf des Konstruktors (ggf. samt Parameter) - Analogie: Wir erzeugen Inhalt
  • Wir lassen die deklarierte Variable darauf referenzieren - Durch eine Zuweisung - Analogie: Wir packen den Inhalt in die Schachtel

1 // Variable deklarieren; es gibt noch kein Objekt! 2 Ellipse e; 3 4 // Objekt erzeugen: Schlüsselwort new 5 // aber das Objekt geht sofort verloren; 6 // wir müssen eine Referenz darauf aufheben 7 new Ellipse(); 8 9 // Also richtig: 10 e = new Ellipse();

Anmerkung: Trennung von Deklaration und Erzeugung in Python? Dieser zweischrittige Prozess kommt Ihnen – aus der Python-Perspektive – sicherlich seltsam vor. Dort werden Variablen nicht deklariert (in einer dyna- misch typisierten Sprache nicht notwendig, eigentlich gibt es ja auch keine Variablen in Python); sie werden bei Bedarf im Moment der Zuweisung er- schaffen.

17.2.6 Zugriff auf Daten

Auf Daten eines Objekts kann wie gewohnt durch Punkt-Notation zugegriffen werden

1 class Ellipse { 2 // Daten deklarieren: 3 double x, y; 4 double achse1, achse2; 5 } 6 7 Ellipse e; 8 e = new Ellipse();

17.3. Methoden 7

4 5 Zeile[] matrix;

17.3 Methoden

17.3.1 Methoden einer Klasse

  • Methoden-Attribute ähnlich zu Python def in Klasse
  • Syntax: - Typ des Rückgabewerts der Methode * Ggf. spezieller Typ^ void^ falls keine Rückgabe - Name der Methode - Parameterliste (auch leer) * Mit Typen * Kein^ self^ als formaler Parameter nötig! - Rumpf der Methode, in geschweiften Klammern als Block
  • In Methodenrumpf - this entspricht self (Schlüsselwort) – implizit statt explizit vor- handen
  • Aufruf: Punktnotation

17.3.2 Klassendeklaration: Beispiel Ellipse mit Methode

1 class Ellipse { 2 // Daten deklarieren: 3 double x, y; 4 double achse1, achse2; 5 6 void verschiebe( double deltax, double deltay) { 7 this .x += deltax; 8 this .y += deltay; 9 } 10 } 11 12 // verkürzte Notation: 13 Ellipse e = new Ellipse(); 14 e.x = 17.12;

8 Liste von Definitionen u.ä.

15 e.verschiebe(5, -0.2); 16 System.out.println(e.x);

e ==> Ellipse@cb644e $3 ==> 17.

17.3.3 Signatur einer Methode

Definition 17.1 (Signatur einer Methode). Die Signatur einer Methode ist festgelegt durch

  • den Namen der Methode
  • die Anzahl und Typen der Parameter.

Anmerkung Der Typ des Rückgabewerts (ggf. void) wird in Java nicht als Teil der Signatur angesehen Signatur in Java. Es gibt Programmiersprachen, bei denen auch das als Teil der Signatur aufgefasst wird.

17.3.4 Überladene Methoden

  • Zwei Methoden der gleichen Klasse müssen unterschiedliche Signatur haben
  • D.h., es kann zwei Methoden gleichen Namens aber unterschiedlicher Parametertypen/-anzahl in einer Klasse geben!
  • Solche Methoden heißen überladene Methoden - Präziser: Der Name der Methode ist überladen; aber hier wird meist schlampig formuliert

Aufruf überladener Methoden? Wie wird beim Aufruf die richtige Methode ausgesucht?

  • Die Typen der Aufrufparameter sind entscheident
  • Ggf. nach impliziten Typecasts - Wähle Methode, die am nächsten bei den Typen des Aufrufs liegt

17.3.5 Überladene Methoden: Beispiele

  • System.out.print!

1 class UeberladeneMethoden { 2 void f( int a) { System.out.println("Variante 1"); }

10 Liste von Definitionen u.ä.

5 6 public static void g(String [] x) { 7 x = new String[] {"lokaler", "Wert"}; 8 } 9 10 public static void main(String [] args) { 11 String [] s = new String[2]; 12 s[0]= "Hallo"; 13 s[1] = "GP1"; 14 System.out.println(s[1]); 15 16 f(s); 17 System.out.println(s[1]); 18 19 g(s); 20 System.out.println(s[1]); 21 } 22 }

GP

Neuer String Neuer String

(PT link)

Visualisierung Um das Verhalten bei unterschiedlicher Nutzung eines Referenz-Parameters darzustellen, hier einige Illustrationen zu diesem Code-Beispiel.

  1. Vor der Zuweisung in f Betrachten wir den Zustand in Abbildung 17.1. Methode f wurde aufge- rufen. Der Parameter x ist eine Referenz auf das gleiche Array, das in main angelegt wurde und dort mit der Variable s referenziert wird.
  2. Nach der Zuweisung in f Abbildung 17.2 ist der Zustand nach der Zuweisung an x[1] in Methode f. Die beiden Variablen s und x zeigen immer noch auf das gleiche Array-Objekt; bei diesem Array wurde der zweite Eintrag verändert. Diese Änderung ist dann auch in main unter s sichtbar und wird dann auch entsprechend ausgegeben.
  3. Vor der Zuweisung in g Der Zustand vor der Zuweisung in g ist in Abbildung 17.3 zu sehen. Hier besteht zunächst kein Unterschied zur Situation beim Aufruf der Methode f.

17.3. Methoden 11

Abbildung 17.1: Methodenaufruf mit Referenzparameter: Vor Zuweisung in f

Abbildung 17.2: Methodenaufruf mit Referenzparameter: Nach Zuweisung in f

  1. Nach der Zuweisung in g Der interessante Teil ist natürlich nach der Zuweisung in g (Abbil- dung 17.4). Der entscheidende Punkt ist, dass hier an die Variable x selbst die Zuweisung erfolgt (und nicht an eine Komponente des Arrays). Dadurch zeigt x jetzt auf ein neues Array , das mit dem Array das durch s referenziert wird, nichts zu hat! Entsprechend verschwinden diese Werte nach der Rückkehr von g.
  2. Nach Rückkehr aus g Abbildung 17.5 bestätigt diese Erwartung: Nach Rückkehr der Methode g ist dieses neue Array (mit den Werten lokaler und Wert ) verschwunden und s hat nach wie vor die vorherigen Werte.

17.3. Methoden 13

Abbildung 17.5: Nach Rückkehr aus g

  • Funktionsaufruf darf nicht an eine Variable zugewiesen werden

Rückgabetyp primitive type

  • return der Methode muss ein Ausdruck des entsprechenden (oder eines kompatiblen) Typs sein
  • Wert wird aus Methode an die Variable des Aufrufers kopiert

Rückgabewert reference type

  • return der Methode muss ein Ausdruck des entsprechenden (oder eines kompatiblen) Typs sein
  • Referenz auf Objekt wird kopiert

17.3.10 Aufrufsemantik: Rückgabewert (2)

Kompatibilitätsregeln

Wie bei allen Zuweisungen auch!

Insgesamt

Im Endeffekt sehr ähnlich zu Python!

17.3.11 Rückgabewert und kompatible Typen

Typ des return Ausdrucks muss zuweisungskompatibel zu Typ in Methoden- signatur sein

14 Liste von Definitionen u.ä.

Beispiel 1: Funktioniert

1 class Ellipse { 2 // (Daten weggelassen) 3 double flaeche() { 4 return 3.1415 * self.achse1 * self.achse2; 5 } 6 }

17.3.12 Rückgabewert und kompatible Typen

Beispiel 2: Funktioniert auch – impliziter typecast

1 class Ellipse { 2 // (Daten weggelassen) 3 double flaeche() { 4 return 3 * (( int ) self.achse1) * (( int ) self.achse2); 5 } 6 }

Beispiel 3: Scheitert – keine implizite Umwandlung möglich

1 class Ellipse { 2 // (Daten weggelassen) 3 int flaeche() { 4 return 3.1415 * self.achse1 * self.achse2; 5 } 6 }

17.3.13 Mehrere Rückgabewerte

  • Das kann Java nicht!
  • Lösung: Klassen definieren - In Method Objekt erzeugen; mit Werten befüllen - Referenz auf diese Klasse zurückgeben
  • Komplexer Ansatz - Führt zu vielen Pseudoklassen, nutzlose Namen,...

17.3.14 Lokale und globale Variablen

Lokale Variablen in Methoden

  • Wie in Python: Methode darf am Anfang lokale Variable deklarieren

16 Liste von Definitionen u.ä.

  • Kennen wir ja schon von public static void main!

17.3.17 Statische und objektbezogene Attribute in Java

Objektbezogen Klassebezogen/statisch Deklaration ohne static mit static Existenz separat in jedem Ob- jekt

1x pro Klasse

Attribut wird ange- legt

bei Objekterzeugung (new)

bei Laden der Klasse (meist: Programman- fang) Attribut wird ver- nichtet

wenn Objekt vernich- tet wird (keine Refe- renz mehr existiert)

wenn Klasse entladen (meist: Programmen- de) Konstruktur bei Objekterzeugung (new)

bei Laden der Klasse

Zugriff auf Datenat- tribut d

obj.d oder this.d Klassenname.d

Aufruf einer Me- thode d

obj.m() oder this.m()

Klassenname.m()

17.3.18 Sichtbarkeit

Definition 17.2 (Sichtbarkeit einer Variablen in Java). Die Sichtbarkeit (oder der Gültigkeitsbereich ) einer Variable erstreckt sich von der Deklaration der Variable bis zum Ende des Blocks, in dem die Deklaration stattfand. Beispielsweise ist die Sichtbarkeit einer Objekt- oder Klassenvariable die Klasse. Für sie gilt zudem eine Ausnahme: Sie sind auch schon vor ihrer Deklaration in allen Methoden der Klasse sichtbar. Eine Variable kann durch eine gleichnamige Variable in einem enthaltenen Block überdeckt werden. Eine Methode kann eine Variable deklarieren, die eine Klassenvariable gleichen Namens überdeckt. (Ein normaler Block darf das nicht.)

17.3.19 Lebensdauer

Definition 17.3 (Lebensdauer einer Variable in Java). Die Lebensdauer einer Variable ist die Zeitspanne, in der die Variable einen gültigen Wert besitzt (der Wert kann eine Referenz auf ein Objekt sein).

Lebensdauer vs. Sichtbarkeit Nicht das gleiche!

17.3. Methoden 17

  • Lebendig, aber nicht sichtbar: Durch andere Variable überdeckt
  • Sichtbar, aber nicht lebendig: Deklariert, aber noch nicht mit Wert ver- sehen

17.3.20 Sichtbarkeit und Lebensdauer: Vergleich

  • Die Konzepte sind in Java und Python grundsätzlich sehr ähnlich
  • Details unterscheiden sich natürlich - Python definiert Lebensdauer von Variablen über Existenz des ent- sprechenden Namensraums - Sonderfall von Klassenvariablen in Java -...

17.3.21 Konstruktoren

  • Konstruktoren im wesentlichen wie in Python
  • Wir haben jeweils einen impliziten Konstruktor benutzt
  • Parameter für Konstruktoren wie bei Methoden - Werte dafür: Parameter beim Klassennamen bei new
  • Konstruktoren können überladen werden

17.3.22 Konstruktoren und Vererbung

Funktioniert das?

1 class Artikel { 2 String artikelnummer; 3 public Artikel(String _an) { 4 this .artikelnummer = _an; 5 } 6 } 7 8 class Book extends Artikel { 9 String ISBN; 10 public Book(String _an, String _isbn) { 11 // das hier verletzt DRY: 12 this .artikelnummer = _an; 13 14 this .ISBN = _isbn; 15 } 16 17 public String toString() { 18 return this .artikelnummer + " -- " + this .ISBN; 19 }

17.3. Methoden 19

Erläuterung

  • Verfügt die Oberklasse über einen default-Konstruktor (= ohne Parame- ter aufrufbar), so wird dieser benutzt - Unterklasse muss den default-Konstruktur nicht explizit aufrufen
  • Gibt es keinen solchen default-Konstruktor in der Oberklasse, so muss der Konstruktor der Unterklasse einen passenden Oberklasse-Konstruktor explizit aufrufen - Mit Schlüsselwort super Zugriff auf Methode der Oberklasse - Konvention: Aufruf muss erste Anweisung im Konstruktor der Un- terklasse sein - Passend: Nach Regeln für überladene Operatoren ausgewählt

17.3.25 getter und setter

  • getter und setter Methoden müssen von Anfang an da sein, wenn benö- tigt - Java hat keinen Mechanismus wie @Property in Python - Wesentlicher Grund: Funktionen sind nicht first-class citizens in Java
  • Manche IDEs: Erzeugen automatisch für alle Attribute getter / setter - Unendliche lange, unübersichtliche Klassen
  • (Die Existenz mächtiger IDEs ist ein Indiz für eine verkorkste Sprache)

17.3.26 Wrappers, Boxing

  • Alle Klassen sind von Object abgeleitet - Damit alle Objekte mit Object zuweisungskompatibel
  • Einfache Typen sind aber keine Klassen - int, char,...
  • Wrapper -Klasse: einen normalen Wert in ein passendes Objekt ein- wickeln - Integer für int, Boolean für boolean, etc.
  • Umständlich, deswegen weitgehend automatisch durch Compiler: Bo- xing und Unboxing

1 Integer intObj = new Integer(42); 2 int x = intObj.intValue();

intObj ==> 42 x ==> 42

20 Liste von Definitionen u.ä.

17.4 Einfachvererbung

17.4.1 Konzept

Klassenhierarchien, die nur Einfachvererbung nutzen, unterscheiden sich kaum (zwischen Python und Java)

  • Marginale Syntaxunterschiede
  • Unterschiede bzgl. Zugriffsrechten

17.4.2 Syntax

  • class Unterklasse extends Oberklasse - Statt: class Unterklasse(Oberklasse):
  • super in Java analog zu super bei Python - Solange nur Einfachvererbung!
  • Beispiel

1 class Book extends Article { 2 // ggf. neue Daten 3 String ISBN; 4 // ggf. neue Methoden oder Methoden überschreiben 5 void showInfo() { 6 // Aufruf der Methode der Oberklasse: 7 super .showInfo(); 8 // und eigene Ausgabe 9 System.out.println("ISBN: " + this .ISBN); 10 } 11 }

17.4.3 Kompatibilität bei Zuweisung

  • Einer Variable vom Typ Oberklasse darf ein Objekt einer Unterklasse zugewiesen werden
  • Umgekehrt: Nein!
  • Beispiel:

1 class Article { 2 String artikelnummer; 3 } 4