JAVA & Objektorientiertes Programmieren

Eine Einführung in das objektorientierte Programmieren mit JAVA Diese Kartei baut auf dem Stoff des Moduls OOP an der HSLU geleitet von Roland Gisler auf.

Eine Einführung in das objektorientierte Programmieren mit JAVA Diese Kartei baut auf dem Stoff des Moduls OOP an der HSLU geleitet von Roland Gisler auf.


Set of flashcards Details

Flashcards 500
Students 19
Language Deutsch
Category Computer Science
Level University
Created / Updated 04.12.2016 / 16.08.2024
Weblink
https://card2brain.ch/box/java_objektorientiertes_programmieren
Embed
<iframe src="https://card2brain.ch/box/java_objektorientiertes_programmieren/embed" width="780" height="150" scrolling="no" frameborder="0"></iframe>

Was sagt die Gleichheitsart Identität aus?

Die absolute Identität eines Objektes steht im Vordergrund.
Gleichheit ist nur dann gegeben, wenn es sich um dasselbe Objekt handel -> die Referenzen sind identisch.

Point point1 = new Point(1,1);
Point point 2 = point1;

point1 und point2 sind ein und derselbe Punkt!

Was sagt die Gleichheitsart Wertegleichheit aus?

Der Zustand eines Objektes steht im Vordergrund.
Attribute enthalten Werte welche den Zustand repräsentieren.
Gleichheit ist dann gegeben, wenn (ausgewählte) Attribute übereinstimmen -> Werte sind gleich.

Point point1 = new Point(3,1);
Point point2 = new Point(3,1);

point1 und point2 sind zwei Objekte, aber gleiche Punkte! (Häufigste Art von Gleichheit)

Was sagt die Gleichheitsart Typgleichheit aus?

Der Typ eines Objektes steht im Vordergrund.
Gleichheit ist bereits dann gegeben, wenn es sich nur um denselben Typ handelt -> dieselbe Klasse.

Point point1 = new Point(3,1);
Point point2 = new Point(2,4);

point1 und point2 sind vom selben dynamischen (!) Typ.

Eine der wenigen Methoden, welche die Klasse Object bereits definiert ist boolean equals (Object obj).

Durch das (optionale) Überladen (override) dieser Methode können (ggf. müssen) wir für jede Klasse (Typ) die gewünschte Art von Gleichheit selber bestimmen.

Durch das (optionale) Überschreiben (override) dieser Methode können (ggf. müssen) wir für jede Klasse (Typ) die gewünschte Art von Gleichheit selber bestimmen.

Wenn wir Objekte auf Gleichheit prüfen wollen, verwenden wir immer welche Methode?

equals()

Weshalb überprüfen wir Objekte immer mit der equals()-Methode auf Gleichheit?

weil der Gleichheits-Operator (==) prüft immer auf Identität!
nur elementare Datentypen dürfen wir mit == vergleichen

Weshalb sollte man Strings nie mit == vergleichen?

String ist ein Klassentyp (nicht elementarer Typ)

Richtig:
String name1 = "Holdrio";
String name2 = "Holdrio";
boolean ever = name1.equals(name2);

Wie ist die equals()-Methode aus Object definiert?

(siehe Bild)

Per Default wird also immer auf die einfachste, aber auch "strengste" Form der Gleichheit als Identität (dasselbe Objekt) geprüft. (Nicht ganz freiwillig: Object hat ja keine Attribute.)

Da wir in einer (grossen) Mehrheit aller Fälle Value Types benötigen, müssen wir die equals()-Methode in der Regeln für jede Klasse was?

Überschreiben, sofern diese z.B. in einer Collection abgelegt werden könnte!

Wie sieht die Dokumentation der equals()-Methode aus?

(siehe Bild)

Was verlangt der equals()-Contract?

Reflexivität bei Vergleich mit sich selbst: x.equals(x) liefert immer true
Symmetrie: x.equals(y) und y.equals(x) liefern das identische Resultat
- Transitivität: Falls x.equals(y) = true und y.equals(z) = true, dann soll auch x.equals(z) = true
- Konsistenz
 bei wiederholten Vergleichen: Bei unveränderten Objekten immer das gleiche Resultat
- Vergleich mit null: x.equals(null) liefert false, also sicher keine NP-Exception!

Wie sieht das equals()-Schema für die Implementation aus?

1. Test auf Identität mit "==" (true bei Identität, schnell)
2. Test auf null (false, weitere Aktionen nicht möglich)
3. Test auf Typen-Vergleichbarkeit (false wenn anderer Typ)
4. Vergleich aller relevanten Attribute der Klasse. Elementare Datentypen: Vergleich mit "==". Vergleich wiederum mit equals().

Hinweis: Schritt 2 und 3 mit instanceOf gemeinsam prüfen
 

Zeige ein Beispiel für die Implementation von equals()

1. Test auf Identität
2. Test auf denselben Typ (und gleichzeitig nicht null)
3. Vergleich der Attributwerte

(siehe Bild)

Attribute von Klassentypen könnten ggf. auch null sein, das muss man vorgängig prüfen, beim Einsatz der Methode equals(). Weshalb?

Da equals() gemäss Contract keine [NullPointer]Exception (Fehler) werfen darf
Klasse Object bietet dafür eine statische Hilfsmethode an: Objects.equals(Object a, Object b)

Was ist eine hash()-Funktion (allgemein)?

Eine Abbildung, die eine grosse Eingabe(daten-)menge auf eine sehr viel kleinere Zielmenge (den Hashwert) abbildet.

Was sind populöre Einsatzgebiete von Hashfunktionen?

- Passwort-Hashes
- Datenübertragung: Sender und Empfänger prüfen, ob der Hashwert identisch ist

Was zeichnet vorallem eine gute Hashfunktion aus?

Eine gute Hashfunktion liefert selbst für kleinste Änderungen in den Eingabedaten einen anderen Hashwert.

Die (nicht mögliche) perfekte Hashfunktion würde für alle unterschiedlichen Eingabedaten was liefern?

z.B. unterschiedliche Hashwerte

Sobald wir equals() überschreiben, müssen wir was machen?

Auch hashCode() überschreiben! equals() wie auch hashCode() werden von einigen Java-Collections verwendet, und sind wichtig für deren korrekte Funktion!

Die Methode hashCode() liefert im Einklang zu equals() quasi was?

die "Adresse des Objektes" als Hashwert.

- Identische Objekte liefern somit dieselben int-Werte.
- Das gilt nur für eine bestimmte Programmausführung (Vorsich bei persistenter Speicherung!)

Der hashCode()-Contract verlangt, dass die Implementation auf derselben Art von Gleichheit basiert wie was?

equals():

- Sind zwei Objekte im Sinne von equals() gleich, müssen auch die Hashwerte identisch sein
- Sind zwei Objekte im Sinne von equals() ungleich, sollten sie idealerweise verschiedene Rückgabewerte liefern

Konsistenz: Wird das Objekt nicht verändert, darf sich bei wiederholtem Aufruf von hashCode() auch der Hash nicht verändern!

Alle Wrapper-Typen (Integer, Long, Float, Double etc.) stellen eine Hilfsmethode int hashCode(...) zur Verfügung. Nenne Beispiele:

Boolean.hashCode(true);
Integer.hashCode(5436);
Double.hashCode(2.73);

Klassentypen: Man delegiert deren hashCode()-Methode weiter. Kann die Referenz null sein, verwendet man zur Vereinfachung die Hilfsmethode Objects.hashCode(...)

Setzt sich der Hashwert aus mehreren Attributen zusammen, kann man die Methode Objects.hashCode(...) verwenden. Sie nimmt eine beliebige Menge von Argumenten entgegen, prüft auf null und berechnet daraus den Gesamthash! 

Stimmt diese Aussage?

Nein, man kann die Methode Objects.hash(...) verwenden.

Zeige ein Beispiel für hashCode() für Klasse Point

(siehe Bild)

Muss man die Methoden equals() und hashCode() immer gemeinsam und konsistent überschreiben?

Ja, sie sollten wenn möglich nur einmal überschrieben und dabei finalisiert (final) werden.

Stell man fest, dass equals() in einer Vererbungshierarchie mehrfach überschrieben wird, oder aber grundsätzlich schwierig korrekt zu implementieren ist, macht man was?

Klassendesign und -hierarchie bzw. Vererbung hinterfragen! Es kann ein Indiz auf schlechte Modellierung sein!

Warum sollte man die bei der Implementation von equals() und/oder hashCode() bei der von der IDE angebotenen Unterstützung immer kritisch bleiben?

Die generierten Methoden sind nicht immer korrekt oder verwenden veraltete Techniken!

Wie testet man equals() und hashCode()?

Sehr aufwendig mit Unit Tests (siehe Bild), aber man kann es auch mit einem EqualsVerifier wie z.B. http://jqno.nl/equalsverifier

Was erlaubt uns das Interface Comparable?

Es erlaubt beliebigen Klassen, sich mit anderen Objekten desselben Typs vergleichbar (im Sinne von kleiner, gleich oder grösser) zu machen.

Für was ist das Interface Comparable eine gute Grundlage?

Die Implementation dieses Interfaces ist eine wichtige Grundlage damit Objekte in Datenstrukturen sortiert werden können.

Wie sieht der compareTo()-Contract aus?

(siehe Bild)

Wie funktioniert im allgemeinen die Methode public int compareTo(T obj) des Interfaces Comparable?

this < other liefert einen negativen Wert (typisch -1)
this = other liefert 0
this > other liefert einen positiven Wert (typisch +1)

Analog zu equals() ist auch hier Symmetrie und Transitivität verlangt

Muss oder sollte die Gleichheit von compareTo() und equals() möglichst analog behandelt werden?

Sollte (kein Zwang, aber meistens sinnvoll)

Wie sieht das Schema zur Implementation von compareTo() aus?

1. Test auf Identität mit "==" (0 bei Identität, schnell)
2. Schrittweiser Vergleich aller relevanter Attribute:
- Elemantare Datentypen, Vergleich mit "==", ">" und "<" möglicht, besser aber compare(...) auf den jeweiligen Wrapper-Typen (Integer, Long, Double, etc.) verwenden.
- Klassentypen: Vergleich jeweils an deren eigene compareTo()-Methode weiter delegieren.

Ist die Reihenfolge beim Vergleich mehrerer Attribute bei der compareTo()-Methode irrelevant?

Nein, sie ist relevant!

Kann man bei der compareTo()-Methode bei Attributen von Referenztypen null-Werte ignorieren?

Nein, man muss unter Umständen null-Werte explizit berücksichtigen!

Zeige ein Beispiel von compareTo() der Klasse Person

(siehe Bild)