OO - Objektorientierte Programmierung

Theoriemix Fragen aus den vergangenen OO-Prüfungen. HSR Hochschule für Technik Rapperswil.

Theoriemix Fragen aus den vergangenen OO-Prüfungen. HSR Hochschule für Technik Rapperswil.


N. S.
Diese Lernkarten behandeln grundlegende und fortgeschrittene Konzepte der objektorientierten Programmierung (OOP) auf Universitätsniveau. Sie decken Themen wie Methoden, Klassen, Objekte, Typen, und Deklarationen ab, wobei der Fokus auf der Implementierung und dem Verständnis von Code liegt. Die Karteikarten sind besonders nützlich für Studierende der Informatik, die ihre Kenntnisse in OOP vertiefen und praktische Beispiele sowie Erklärungen zu komplexen Konzepten wie Method Overloading und Overriding benötigen.
Karten
58
Lernende
1
Sprache
Deutsch
Kategorie
Informatik
Stufe
Universität
Erstellt / Aktualisiert
23.06.2016 / 27.06.2016

Lernkarten

Ausdruck: 1 / 0

Ergebniswert: Fehler: / by zero, ArithemticException
Ergebnistyp: -

Ausdruck: "AB" == new String("AB")

Ergebniswert: false
Ergebnistyp: boolean

Ausdruck: "ABC".equals("abc")

Ergebniswert: false
Ergebnistyp: boolean

Ausdruck: '9' - '0'

Ergebniswert: 9
Ergebnistyp: int

Ausdruck: -3 / 2

Ergebniswert: -1
Ergebnistyp: int

Ausdruck: -3.0 / 2

Ergebniswert: -1.5
Ergebnistyp: double

Ausdruck: 0 / 1

Ergebniswert: 0
Ergebnistyp: int

Ausdruck: 0 / 1.0

Ergebniswert: 0.0
Ergebnistyp: double

Ausdruck: 0.0 / 0.f

Ergebniswert: NaN, (Double.NaN)
Ergebnistyp: double

Ausdruck: 1 + 2 * 3

Ergebniswert: 7
Ergebnistyp: int

Ausdruck: 1 / 0.0

Ergebniswert: Infinity, (Double.POSITIVE_INFINITY)
Ergebnistyp: double

Ausdruck: 1 < 2

Ergebniswert: true
Ergebnistyp: boolean

Ausdruck: 1 == 2 && 0 / 0 == 0

Ergebniswert: false
Ergebnistyp: boolean

Ausdruck: 1 == 2 || 0 / 0 == 0

Ergebniswert: Fehler: / by zero, ArithemticException
Ergebnistyp: -

Ausdruck: 1 – (2 * 3) + 4

Ergebniswert: -1
Ergebnistyp: int

Ausdruck: 1 – 2 * 3 + 4

Ergebniswert: -1
Ergebnistyp: int

Folgender Code ist stilistisch unschön. Verbessern Sie ihn.

 

Betrachten Sie folgende Klassen- und Variablen-Deklarationen: (Siehe Bild)

Welche Methode wird jeweils aufgerufen? Geben Sie an, wenn es dabei Fehler gibt.

c.moveTo(g);
c.moveTo(c);
g.moveTo(c);
g.moveTo(g);
((Graphic)c).moveTo(g);
((Circle)g).moveTo(c);

Method 2

Method 3

Method 2

Method 2

Method 2

Method 3

Wieso soll bei Überschreiben von equals() jeweils auch die hashCode()-Methode
überschrieben werden? Was kann sonst passieren?

Inkonsistenzen beim Hashing (HashMap, HashSet etc.): Element wird allenfalls
nicht gefunden, obwohl es in der Hash-Tabelle existiert.


Es muss gelten: Falls x.equals(x), dann muss x.hashCode() == y.hashCode() ergeben
(Umkehrung muss nicht unbedingt gelten).

Bestimmen Sie die Variablenzustände nach den folgenden Anweisungen.

int a = 0, b = 0, c = 0;
boolean d = (a++ > 0 && b-- < 0) || --c < 0;

Variable | Zustand am Schluss
-----------------------------------------
a: 1
b: 0
c: -1
d: true

Gegeben sind zwei Klassen: (Siehe Bild)

Was gibt der untenstehende Code aus? Erklären Sie kurz.

Base b = new Derived();
b.print();

Überschriebenes getKind() wird hier wegen Dynamic Dispatch immer aufgerufen, egal ob der Aufruf in Base oder Derived steht. Ausgabe:


Derived
Derived

Gegeben sind drei überladene Methoden:

int round(int x); /* Methode 1 */
double round(double x); /* Methode 2 */
Integer round(Integer x); /* Methode 3 */

Welcher der drei Methoden wird jeweils aufgerufen?

  1. double r = round(2);
  2. double r = round(1.0);
  3. Integer r = round(1);
  4. round(null);

  1. Methode 1
  2. Methode 2
  3. Methode 1
  4. Methode 3

Schreiben Sie eine Funktionsschnittstelle, zu welcher das Lambda kompatibel ist.

(a, b) -> a.contains(b)

interface Comparison<A, B> {
   boolean areEqual(A a, B b);
}

Das try-with-resources Statement wird zum Beispiel bei IO Streams eingesetzt.

try(InputStream stream = new FileInputStream("datafile")) {
   …
}

Angenommen, es gäbe in Java kein solches try-with-resources. Wie würden Sie es sonst programmieren?

InputStream stream = new FileInputStream(“datafile”);
try {
   …
} finally {
   stream.close();
}

Betrachten Sie die generische Klasse Pair. Welche Type Bounds fehlen noch?

Was ist eine Checked Exception? Eine kurze Erklärung reicht.

  • Klasse, die von Throwable erbt, aber nicht von RuntimeException und nicht von Error
  • Exception, die in den auftretenden Methoden behandelt oder per throws-Klausel deklariert werden muss.

Der Ausdruck 0.1 + 0.1 + 0.1 == 0.3 ergibt wider Erwarten false. Erklären Sie wieso. Wie
soll man stattdessen die Gleichheit prüfen?

Gleitkommazahlen sollten nicht auf exakte Gleichheit überprüft werden, sondern ob ihre Differenz
sehr klein (abhängig vom Anwendungsfall) ist. Math.abs(x – y) < epsilon.

Jemand beobachtet ein sonderbares Verhalten: Der linke Code ergibt die Ausgabe true, der
rechte fast identische Code aber false. Was macht er grundsätzlich falsch? Wie müsste man es
korrekt lösen?

Hier handelt es sich um Wrapper-Objekte und der Vergleich ist ein Referenzvergleich. Die Zahlen
können dabei durch das Boxing in unterschiedlichen Objekten gespeichert sein, so dass der
Vergleich grundsätzlich false ist. Nur falls das Laufzeitsystem dies optimiert (z.B. Cache), könnten
beim Boxing dasselbe Objekt für bestimmte Zahlen verwendet werden, so dass es true ist.

Gegeben sind zwei Klassen. (Siehe Bild)

Welche der obigen Methoden wird nachfolgend jeweils aufgerufen? Begründen Sie kurz.

1. Methode 1, Methode 2, Methode 3 oder Methode 4? Und Warum?

Rectangle a = new Rectangle();
Rectangle b = new Rectangle();
a.surround(b);

2. Methode 1, Methode 2, Methode 3 oder Methode 4? Und Warum?

Figure a = new Rectangle();
Rectangle b = new Rectangle();
a.surround(b);

3. Methode 1, Methode 2, Methode 3 oder Methode 4? Und Warum?

Rectangle a = new Rectangle();
Figure b = new Rectangle();
a.surround(b);

4. Methode 1, Methode 2, Methode 3 oder Methode 4? Und Warum?

Figure a = new Rectangle();
Figure b = new Rectangle();
a.surround(b);

  1. Methode 4, wegen dynamic dispatch und overload mit statischem Typ Rectangle.
  2. Methode 4, wegen dynamic dispatch und overload mit statischem Typ Rectangle.
  3. Methode 3, wegen dynamic dispatch und overload mit statischem Typ Figure.
  4. Methode 3, wegen dynamic dispatch und overload mit statischem Typ Figure.

Was geschieht bei der Ausführung der Methode test(). Geben Sie die einzelnen Schritte an.

  1. first
  2. null
  3. length
  4. NullPointerException

Strings sollen mit equals() und nicht mit == verglichen werden. Erklären Sie wieso. Geben Sie zudem ein Beispiel an, wie es mit == schiefgehen könnte.

== ist nur Referenzvergleich: Der gleiche String-Text kann auch in verschiedenen Objekten gespeichert sein.

Beispiele, wo es schiefgeht:
“Prog1” != new String(„Prog1“)
„Prog1“ != „Prog1“ (wenn es kein String Pool gibt)

Daher (und auch um unabhängig von Annahmen zu String-Pool Optimierungen zu bleiben) wird equals() zum semantischen Vergleich (gleiche Textsequenz) benutzt.

Es soll geprüft werden, ob int[] a aus zwei gleichen Elementen besteht. Welche der untenstehenden Varianten ziehen Sie vor? Begründen Sie Ihre Wahl.

Erste Variante, weil es wegen der bedingten Auswertung keine ArrayIndexOutOfBoundsException für Array-Länge kleiner als 2 gibt.

Im folgenden Code wird der close()-Aufruf nicht ausgeführt, wenn es in analyze() eine unbehandelte Exception gibt. Korrigieren Sie den Code, sodass close() in jedem Fall aufgerufen wird, d.h. mit und ohne Exception in analyze().

InputStream stream = new FileInputStream("test");
analyze(stream);
stream.close();

try (InputStream stream = new FileInputStream("test")) {
   analyze(stream);
}

oder mit explizitem try-finally

Erklären Sie den Unterschied zwischen den zwei Konzepten:

  • Überladene Methoden („Method Overloading“)
  • Überschriebene Methoden („Method Overriding“)

Overloading: Methode mit gleichem Namen (Identifier), aber unterschiedlicher Parameterliste (unterschiedliche Anzahl oder Typen der Parameter). Auflösung statisch (durch Compiler).


Overriding: Methode mit gleicher Signatur (gleicher Identifier und Parameterliste) wird in Subklasse (oder implementierende Klasse einer Schnittstelle) erneut implementiert. Auflösung dynamisch (virtual Call/dynamic Dispatch durch Laufzeitsystem).

Man betrachte folgende zwei Klassen. (Siehe Bild)

Welche Ausgaben ergeben nachfolgende Szenarien. Geben Sie eine kurze Begründung an.

Base a = new Sub();
a.print1();

-----------------------------

Base b = new Sub();
b.print2();

Ausgabe: Sub
Begründung:
Dynamic Dispatch: Der dynamische Typ von a entscheidet welche Methode von getValue() aufgerufen wird. Hier ist das die überschriebene Methode getValue() in Sub.

Ausgabe: Base
Begründung:
Variablen werden nicht dynamisch gebunden. Der statische Typ entscheidet, welche Variable in print2() zugegriffen wird. Hier ist dies value von Base, auch wenn diese in Sub versteckt („Hiding“) wird.

Was sind die Resultate von x, y und b?

int x = 0;
int y = 0;
boolean b = x++ > 0 && --y < 0;

false

Führen Sie eine Stil-Verbesserung durch:

if (x > y) {
   return true;
} else {
   return false;
}

return x > y;

Führen Sie eine Stil-Verbesserung durch:

if ( a == true ) { ... }

if ( a ) { ... }

Führen Sie eine Stil-Verbesserung durch:

if ( a == false ) { ... }

if ( !a ) { ... }

Ausdruck: 1 * 2 + 3 * 4

---

Gegeben sind diese Deklarationen:
short s = 1; int i = 2; float f = 3;
int a = 0, b = 1;
boolean x = true, y = false;

Ergebniswert: 14
Ergebnistyp: int

Lernen