Skip to content

Latest commit

 

History

History
722 lines (584 loc) · 19.6 KB

Kap.10.adoc

File metadata and controls

722 lines (584 loc) · 19.6 KB
Tip

Hinweis: Tabelle 10.1, Modifizierer, müssen Sie können.

Frage

Herr Kofler nennt welche Vorteile, die Objektorientierung bietet?

Antwort
  • Bessere Strukturierung des Codes

  • Kapselung von Daten

  • Bessere Wiederverwertbarkeit

  • Pakete und Klassenbibliotheken

Frage

Wann ist eine Klasse keine Top-Level-Klasse?

  • ❏ Wenn die Klasse nicht oben im Quellcode steht.

  • ✓ Wenn die Klasse innerhalb von geschweiften Klammern steht.

  • ❏ Wenn die Klasse static ist.

  • ❏ Wenn die Klasse abstract ist.

Frage

Kann man eine Klasse derart in einer Methode deklarieren und nutzen?

void foo() {
 class StrangeThing {
   boolean isStrange = true;
 }
 StrangeThing thing = new StrangeThing();
 System.out.println(thing.isStrange);
}
  • ✓ Ja, es handelt sich hier um eine lokale Klassendefinition

  • ❏ Ja, es ist egal, ob eine Klasse in einer Methode deklariert wird oder umgekehrt

  • ❏ Nein, die Klasse müsste public sein.

  • ❏ Nein, die Klasse müsste static sein.

Frage

Wie sieht schematisch die Syntax zur Deklaration einer Klasse aus [ohne Annotationen und Generics]?

Antwort
[Modifizierer] `class` Name
  [`extends` NameOberKlasse]
  [`implements` I1, I2, ...] `{`
  // Klassenrumpf (class body)
`}`

Frage

In einer .java-Datei können mehrere Klassen deklariert werden. Allerdings gilt eine Einschränkung, was den Namen der Datei angeht. Welche?

  • ❏ Der Name der Datei muss mit dem Namen der ersten Klasse in der Datei übereinstimmen.

  • ❏ Der Dateiname muss wie der Klassenname mit einem Großbuchstaben beginnen.

  • ❏ Der Dateiname muss die Endung .class haben.

  • ✓ Wenn eine der Klassen public ist, muss der Name der Datei dem Namen dieser Klasse entsprechen.

Frage

Schreibe class test und schon ist der Kopf ab, bevor auch nur ein { folgt. Warum? [Gemeint ist Ihr Kopf, nicht der der Klassendeklaration (-:]

  • ❏ Vor class fehlt ein public.

  • ❏ Es muss Class test heißen.

  • ✓ Es muss class Test heißen.

  • ❏ Der Name test ist reserviert und darf nicht benutzt werden.

Antwort

Namen von Klassen beginnen immer mit einem Großbuchstaben! Zwar ist das eine Konvention, an die sich aber ausnahmslos alle Java-Entwickler/innen halten.

Frage

Eine Top-Level-Klasse darf wie nicht deklariert sein?

  • ❏ public

  • ❏ paketsicher

  • ✓ private

  • ✓ protected

Frage

Gibt es in Java das Laufzeitkonstrukt der Klasse?

Antwort

Nein. Zu einer Klasse class A {} gibt es kein Laufzeitkonstrukt, womit man auf die Klasse direkt zugreifen könnte. Mit A.class erhält man lediglich Zugriff auf ein Objekt, das eine Beschreibung der Klasse A darstellt. Diese Fähigkeit zur Selbstauskunft über die deklarierten Eigenschaften der Klasse nennt man Reflektion (reflection). Für eine Instanz der Klasse bekommt man mit getClass() an das Objekt, das die Klasse A beschreibt.

Frage

Gibt es in Java das Laufzeitkonstrukt des Objekts?

Antwort

Ja. Die Instanzen einer Klasse, gemeinhin als Objekte bezeichnet, existieren ausschließlich zur Laufzeit.

Frage

class Thing {
  private class PartOfThing {
    String name = "part";
  }
}

Geht das?

Antwort

Ja, das geht. Die Klasse PartOfThing ist allerdings nur innerhalb des Rumpfs von Thing verwendbar.

Frage

class Thing {
  private class PartOfThing { }
  public PartOfThing pot = new PartOfThing();
}

Wie kann auf pot innerhalb des Pakets zugegriffen werden?

  • Thing.pot

  • new Thing().pot

  • new Thing.PartOfThing().pot

  • ✓ gar nicht

Antwort

Auf die private, innere Klasse kann von außen weder zugegriffen werden, noch sind Instanzen dieser privaten Klassen zugreifbar, selbst wenn die Klassenvariable public ist!

jshell> Thing.pot
|  Error:
|  non-static variable pot cannot be referenced from a static context
|  Thing.pot
|  ^-------^

jshell> new Thing().pot
|  Error:
|  Thing.PartOfThing has private access in Thing
|  new Thing().pot
|  ^

jshell> new Thing.PartOfThing().pot
|  Error:
|  Thing.PartOfThing has private access in Thing
|  new Thing.PartOfThing().pot

Frage

class Thing {
  class PartOfThing { }
  public PartOfThing pot = new PartOfThing();
}

Wie kann auf pot innerhalb des Pakets zugegriffen werden?

  • Thing.pot

  • new Thing().pot

  • new Thing.PartOfThing().pot

  • ❏ gar nicht

Frage

Auf welcher Ebene ist die Klasse class A {} sichtbar?

Antwort

Auf der Paketebene. Wenn kein Modifizierer vorhanden ist, ist die Klasse paketsicher.

Frage

Was ist eine Klassenvariable? Doch dasselbe wie ein statisches Feld, oder?

Antwort

Für Herrn Kofler sind "Klassenvariablen" einfach nur beliebige Felder, egal ob sie static sind oder nicht. Die Terminologie ist hier in der Literatur nicht eindeutig.

Frage

Klären Sie die Begriffe "Feld" (engl. field) und "Variable".

Antwort

"Felder" sind Variablen, die im Rumpf einer Klasse deklariert werden.

Frage

class Thing {
 public String name;
}

Kann man auf das Feld name von anderen Paketen aus zugreifen?

Antwort

Nein, da man auf die Klasse Thing nicht aus anderen Paketen zugreifen kann.

Frage

Im Rumpf einer Klasse können welche Sprachkonstrukte deklariert werden?

Antwort

Methoden, Felder, Klassen, Interfaces und Enums.

Frage

class Point {
 private int x,y;
 Point(int x, int y) { this.x = x; this.y = y; }
 boolean equals(Point other) {
   return this.x == other.x && this.y == other.y;
 }
}

Ist der Zugriff auf das private Feld other.x erlaubt?

Antwort

Ja, weil die Sichtbarkeit private sich auf allen Code innerhalb der Klasse bezieht. Es ist egal, welches Objekt auf das Feld zugreift, so lange der Zugriff aus irgendeiner Methode der Klasse Point erfolgt.

Frage

Was ist mit dem Begriff "paketsicher" gemeint?

Antwort

"Paketsicher" bezeichnet die default-Sichtbarkeit von Klassen und Feldern (wenn kein Sichtbarkeitsmodifizierer angegeben wurde). Auf "paketsichere" Klassen und Felder kann man innerhalb des Pakets zugreifen in dem sie deklariert wurden.

Frage

Mit welchem Modifizierer kann man die Voraussetzung für einen immutablen (unveränderlichen) Datentyp schaffen? Reicht die Verwendung dieses Modifizierers allein schon aus, um die Immutabilität zu garantieren?

Antwort

Wenn ein Datentyp (eine Klasse) immutabel sein soll, müssen alle ihre Felder final sein. Das reicht allerdings noch nicht aus. Zusätzlich müssen alle Felder selbst einen immutablen Datentyp haben, oder es muss sichergestellt werden, dass niemand sonst eine Referenz auf interne Daten der Klasse haben kann.

Frage

Nennen Sie die einzelnen Schritte, die bei einem Aufruf von new ausgeführt werden.

Antwort
  • Speicherplatz für die nicht-statischen Felder der Klasse wird zugeteilt.

  • Außerdem wird eine Refenz zu der Klasse angelegt, von der ein Objekt erzeugt werden soll (um z.B. den Code von Methoden nachschlagen zu können).

  • Die Felder werden mit 0, false oder null initialisiert.

  • Der Konstruktor wird aufgerufen.

  • Eine Referenz auf das erstellte Objekt wird zurückgegeben.

Frage

Wie sieht das Schema zum Zugriff auf eine statische Variable bzw. zum Aufruf einer statischen Methode aus?

Antwort

Klassenname.variablenname bzw. Klassenname.methodenname.

Frage

Recherchieren Sie: In der OOP-Veranstaltung hatten wir ein Beispiel, in dem wir eine statische Klassenvariable genutzt haben. Worum ging es bei dem Beispiel? Welchen Zweck hatte die statische Klassenvariable?

Antwort

Es ging um eine Klasse Thing mit einer ID, die sich in einem statischen Feld merkt, welche IDs schon vergeben wurden.

Frage

class Point {
 int x = 0, y = 0;
 Point(int x, int y) { this.x = x; this.y = y; }
}
Point p = new Point();

Autsch! Warum?

Antwort

Der Default-Konstruktor existiert nur, wenn kein anderer Konstruktor definiert wurde. In diesem Fall gibt es den Konstruktor Point() also nicht.

Frage

Deklarieren Sie eine Klasse, von der keine Objekte erzeugt werden können.

Antwort

class Math { private Math() {} } oder abstract class Thing {}.

Frage

Ein Konstruktor ist mit einer Methodendeklaration sehr vergleichbar. Nur: Der Konstruktor hat zwar einen Namen, ihm scheint jedoch der Rückgabetyp zu fehlen. Warum?

Antwort

Der Rückgabetyp eines Konstruktors ist immer die Klasse in der er deklariert wurde.

Frage

Was sind die Defaultwerte für Felder (Klassenvariablen)? Was sind die Defaultwerte für lokale Variablen?

Antwort

Die Defaultwerte für Felder sind 0 und false für primitive Typen bzw. null für Referenztypen. Lokale Variablen haben keine Defaultwerte.

Frage

Warum kann man finalize nicht für Aufräumarbeiten verwenden?

Antwort

finalize wird aufgerufen, wenn der Garbage-Collector das Objekt löscht. Es ist nicht garantiert, wann oder ob das überhaupt geschieht.

Frage

Wie ruft man im Konstruktor einen anderen Konstruktor der gleichen Klasse auf? Warum sollte man das überhaupt tun wollen?

Antwort

this(Parameter);

Frage

class A {
 int a,b;
 A() {
   a = 0;
   this(0);
 }
 A(int x) {
   a = 1;
   b = x;
 }
}

Autsch! Warum?

Antwort

Vor dem Konstruktoraufruf this(0); darf kein anderer Ausdruck stehen.

Frage

Im Vorgriff auch das nächste Kapitel: Wie ruft man im Konstruktor den Konstruktor der Oberklasse auf?

Antwort

super(Parameter);

Frage

Was ist die Besonderheit des Interfaces AutoCloseable? Welche Methoden deklariert es?

Antwort

Das Interface deklariert nur die Methode close. Klassen, die das Interface AutoCloseable implementieren, können in einem try-with-resources verwendet werden.

Frage

Ist this eine Variable?

Antwort

Streng genommen nein (this ist ein Schlüsselwort), aber man kann es gedanklich wie eine Variable behandeln.

Frage

Ist es nicht das gleiche, ob eine Klasse jetzt ein public int x definiert oder ein private int x mit den Methoden int getX() und void setX(int x)? Wo liegt der Unterschied?

Antwort

Mit den Methoden hat man mehr Kontrolle darüber, was mit dem Feld geschieht (z.B. welche Werte bei einem setX zulässig sind, oder welche Variablen tatsächlich hinter einem getX steht).

Frage

Wozu benötigt man this?

Antwort

Um einen Konstruktor in einem anderen Konstruktor aufzurufen und um ein Feld von einer lokalen Variable mit gleichem Namen zu unterscheiden.

Frage

Wenn man sich in den Namensgebungen für Parameter und lokale Variablen diszipliniert, benötigt man dann überhaupt noch this?

Antwort

Ja, für den Aufruf eines Konstruktors oder wenn this zurückgegeben oder an eine andere Methode übergeben werden soll.

Frage

Wenn an den Konstruktor "falsche" Werte übergeben werden, empfiehlt es sich mit einer Exception darauf zu reagieren. Welche Exception sollte man wählen, sofern man nicht spezifischer sein kann/möchte?

Antwort

IllegalArgumentException

Frage

Wenn es einen Konstruktor gibt, muss es auch einen Destruktor geben, nicht wahr?! Hat Java einen Destruktor? Begründen Sie Ihre Antwort!

Antwort

Nein, es gibt nur die Methode finalize, die aufgerufen wird, wenn der Garbage-Collector das Objekt löscht. (Achtung: Es kann nicht garantiert werden ob und wann das geschieht.)

Frage

Eine Klasse, die eine close-Methode anbietet sollte die Schnittstelle AutoCloseable implementieren. Warum?

Antwort

Damit die Klasse mit einem try-with-resources verwendet werden kann.

Frage

Was ist mit "Settern" und "Gettern" gemeint?

Antwort

Getter und Setter sind Methoden die das Lesen bzw. Schreiben von internen Daten einer Klasse kontrollieren.

Frage

Was ist damit gemeint, wenn man von einer "Datenklasse" spricht?

Antwort

Eine "Datenklasse" tut nichts anderes als Werte zu speichern. Die Klasse hat dann nur Felder, Getter und Setter.

Frage

Wenn Sie Setter- und Getter-Methoden implementieren, dann sollten die Felder wie deklariert sein?

Antwort

private

Frage

Oft sieht man Setter wie public setName(Typ value) { name = value; }. Was könnte man daran kritisieren?

Antwort

Dieser Setter macht nicht viel Sinn, da er sich genau so verhält als wäre die Variable name öffentlich deklariert.

Frage

Aufgrund welchen Prinzips der Softwaretechnik werden Setter und Getter begründet?

Antwort

Es geht um das Geheimnisprinzip, das besagt, dass von außen niemand wissen soll, wie die Datenhaltung innerhalb eines Objekts implementiert ist.

Frage

Welcher softwaretechnische Nutzen steckt vor allem in den Setter-Methoden?

Antwort

Setter ermöglichen es, zu kontrollieren welche Werte für ein Feld erlaubt sind.

Frage

Warum ist der Begriff "Unterklasse" für eine innere Klasse problematisch?

Antwort

Der Begriff "Unterklasse" wird meist für die abgeleitete Klasse einer Oberklasse genutzt. Bitte eine innere Klasse nicht als Unterklasse bezeichnen.

Frage

class A {
  int x;
  class B {
    int x;
    int foo(int x) {
       // zähle alle drei mit x benannten Variablen zusammen
    }
  }
}

Welcher Code muss an der markierten Stelle stehen, um den Wert von allen drei Variablen zusammenzuzählen? Wie unterscheidet man sie voneinander?

Antwort

Wir streuen in die Lösung zum Verständnis ein paar Ausgaben ein.

class A {
  int x;
  class B {
    int x;
    int foo(int x) {
      System.out.println(x);
      System.out.println(this.x);
      System.out.println(A.this.x);
      System.out.println(B.this.x);
      // System.out.println(x);
      return x + this.x + A.this.x; // this.x oder B.this.x
    }
  }
}
jshell> new A()
$37 ==> A@335eadca

jshell> $37.new B()
$38 ==> A$B@eec5a4a

jshell> $38.foo(3)
$39 ==> 3

Eine Top-Level-Klasse als static zu deklarieren ist sinnfrei, da die Klasse an nichts "hängt" und nur Teil eines Pakets ist.

Frage

this.name oder name.this, das ist hier die Frage!

Antwort

Beides ist gültig, je nach Kontext. Im zweiten Fall ist name jedoch ein Klassenname und sollte eigentlich — unserer Konvention der Großschreibung für Klassennamen folgend — als Name.this geschrieben werden.

Frage

AutoCloseable a = new AutoCloseable() {
  public void close() { System.out.println("closed"); }
}

Warum geht das, obwohl AutoCloseable a = new AutoCloseable(); einen Fehler produziert?

Antwort

Hier liegt eine anonyme Klasse vor, die nach ihrer Implementierung sofort instanziiert wird.

Frage

Kann eine anonyme Klasse einen Konstruktor haben? Warum, oder warum nicht?

Antwort

Wenn es keinen Namen für die Klasse gibt, sie ist ja anonym (= hat keinen Namen), kann man keinen Konstruktor deklarieren.

Frage

class A {
    static int b;
    class C {
        static int d;
    }
}

Sie dürfen eine Sache streichen, damit der Code gültig wird.

Antwort

C ist eine lokale Klasse, sie darf keine statischen Members haben. Streiche static bei int d.

Frage

Erzeugen Sie eine anonyme Unterklasse von java.awt.Point, die die Methode toString so überschreibt, dass die String-Repräsentation jetzt einfach der mathematischen Schreibweise (x, y) entspricht. Wie können Sie beim Erzeugen des Objektes dieser Klasse die Koordinaten x und y übergeben?

Antwort
java.awt.Point p = new java.awt.Point() {
    public String toString() {
        return "(" + x + ", " + y + ")";
    }
}

Die anonyme Klasse ist eine Unterklasse von java.awt.Point.

jshell> java.awt.Point p = new java.awt.Point() {
   ...>     public String toString() {
   ...>         return "(" + x + ", " + y + ")";
   ...>     }
   ...> }
p ==> (0, 0)

jshell> p.x = 10
$41 ==> 10

jshell> p
p ==> (10, 0)

Frage

Object obj = new Object() {
  public void myFancyNewMethod() { /* do stuff */ }
}

Macht das Sinn?

Antwort

Die Optik verstellt Ihnen hier vermutlich den Blick. new Object() ist eine anonyme Klasse, die eine Unterklasse von Object ist. Der Typ von obj ist hingegen vom Typ Object. Wenn man mit obj eine Methode wie myFancyNewMethod aufrufen will, beginnt die Suche nach der Methode im Typ Object, nicht in der anonymen Unterklasse! Die Methode ist also sinnfrei.

Frage

Eine Instanz einer anonyme Klasse kann nur auf bestimmte Variablen des Kontextes zugreifen, in dem sie erzeugt wurde. Welche Variablen sind das?

Antwort

Variablen müssen final sein.

Frage

Definieren Sie, was effectively final heißt?

Antwort

Eine Variable ist "effectively final", wenn sie zwar nicht als final deklariert ist, der Compiler aber eine Deklaration mit final zulassen würde.

Frage

AutoCloseable a = () → System.out.println("auto"); Wie nennt man so etwas?

Antwort

Das ist ein Lambda-Ausdruck, erkennbar am Pfeil .

Frage

String message = "foo";
AutoCloseable a = new AutoCloseable() {
  public void close() { System.out.println(message); }
};
message = "bar";

Alles in Butter, oder doch nicht?

Antwort

Das message nicht effectively final ist, darf die anonyme Klasse nicht auf message zugreifen.

Frage

class A {
   static int b;
   class C {
       static int d;
   }
}

Sie dürfen eine Sache ergänzen, damit der Code gültig wird.

Antwort

Die Klasse C muss um ein static ergänzt werden.

Frage

Warum sind laut Herrn Kofler statische innere Klassen gar keine "inneren Klassen" im eigentlichen Sinne?

Antwort

Die "innere" Klasse ist wie eine eigenständige Klasse behandelbar.

Frage

Kann man eine Klasse mit dem qualifizierten Namen A.B.C definieren? Wenn ja, wie? (Die Punkte sind Teil des Namens.)

Antwort

Man kann es machen. In einer Klasse A ist eine Klasse B, in der sich eine Klasse C befindet.