Fragen zur Java-Zertifizierung, Überladen, Überschreiben, Typen zur Laufzeit und Objektorientierung

Frage

Das Design einer Klasse erfordert, dass eine Instanzvariable von Unterklassen verändert werden kann. Klassen, die allerdings im gleichen Paket liegen, sollen keinen Zugriff haben. Wie muss der Modifier gewählt werden, so dass dies möglich wird?

  1. public
  2. private
  3. protected
  4. Kein besonderer Modifier.
  5. private und die es sollte Zugriffsmethoden geben.

Public würde die Variable für alle sichtbar machen, daher ist A falsch. Private würde die Variable auch für Unterklassen unsichtbar machen, daher ist auch B falsch. C ist korrekt, da die Variable von erbenden Klassen geändert werden kann. Gibt man keinen Modifier an, so können auch Klassen im gleichen Paket (also Verzeichnis) die Variable verändern. Dies ist aber in der Aufgabe verboten. So ist auch D falsch. Obwohl Zugriffsmethoden im Design einer Klasse zu einer schöne Modellierung führt, verbieten diese jedoch nicht, dass nur Methoden der Unterklassen auf die Variablen zugreifen können. Also ist auch E falsch.

Frage

Was passiert, wenn folgende Klasse compiliert und ausgeführt wird?

class Test
{
  static int myArg = 1;
  public static void main( String args[] )
  {
    int myArg;
    System.out.println( myArg );
  }
}
  1. Der Code lässt sich kompilieren und bei der Aufführung erscheint 0 auf dem Bildschirm.
  2. Der Code lässt sich kompilieren und bei der Aufführung erscheint 1 auf dem Bildschirm.
  3. Dieses Programmstück lässt sich nicht kompilieren, da eine lokale Variable nicht den gleichen Namen besitzen darf, wie eine statische Variable.

  4. Dieses Programmstück lässt sich nicht kompilieren, da die lokale Variable vor der Nutzung noch nicht initialisiert ist.

Der Programmcode wird nicht kompiliert, da myArg nicht initialisiert wurde, Antwort D ist korrekt. A ist falsch, da lokale Variablen nicht automatisch mit 0 initialisiert werden. B ist falsch, da der Zugriff erst auf innere Variablen erfolgt.

Frage

Welches der folgenden Code Fragmente ist geeignet, um die Anzahl der Argumente, die einer Java Applikation übergeben werden, in count zu speichern. Die Deklaration der main() Funktion ist wie folgt:

public static void main( String args[] )
{
  // Hier den Block einsetzen
}
  1. int count = args.length;
  2. int count = args.length – 1;
  3. int count = 0;

    while ( args[count] != null )

      count++;

  4. int count = 0;

    while ( !(args[count].equals("") ) )

      count++;

A ist korrekt. B ist falsch, da in Java der Name des Programmes nicht im ersten Argument steht und daher der Zähler nicht erniedrigt werden muss. Da alle Argumente gültige Strings sind, kann C nicht richtig sein. Leerstring können ebenso nicht in der Folge vorkommen, daher ist auch D falsch.

Frage

Analysiere die folgenden beiden Klassen:

final class First
{
  static int a = 3;
}
class Second extends First
{
  public void method() {     System.out.println( a );
  }
}
  1. Die Klasse First lässt sich kompilieren, aber nicht die Klasse Second.
  2. Die Klasse Second lässt sich kompilieren, aber nicht die Klasse First.
  3. Keine der beiden Klassen lässt sich kompilieren.
  4. Beide Klassen lassen sich kompilieren und wenn method() aufgerufen wird, schreibt es 3 auf die Standardausgabe.
  5. Beide Klassen lassen sich kompilieren, aber ein Aufruf von method() mündet in eine Exception.

Die Klasse First lässt sich problemlos kompilieren. Die Kompilation der Klasse Second scheitert jedoch daran, dass man final Klassen nicht erweitern kann. So ist A, C und D falsch und B die richtige Antwort. C ist falsch, da sich First kompilieren lässt.

Frage

Was passiert, wenn folgender Programmcode kompiliert und die main() Methode von B aufgerufen wird?

class A {
  int i;
  A( int i ) {
    this.i = i*2;
  }
}
class B extends A {
  public static void main( String args[] ) {
    B b = new B(2);
  }
  B( int i ) {     System.out.println( i );
  }
}
  1. Die Instanzvariable i bekommt den Wert 4.
  2. Die Instanzvariable i bekommt den Wert 2.
  3. Die Instanzvariable i bekommt den Wert 0.
  4. Der Code lässt sich nicht kompilieren.

Da sich der Programmcode nicht kompilieren lässt ist A, B und C falsch und D richtig. In der Vererbung ruft der Konstruktor der Klasse B den Standard-Konstruktor von A auf. Dieser existiert aber nicht. Um da Programm zum Laufen zu bringen, muss im Konstruktor B(int) mit super() der parametrisierte Konstruktor in A aufgerufen werden.

Frage

Was ist an folgendem Programmstück falsch?

final class First
{
  private int a = 1;
  int b = 2;
}
class Second extends First
{
  public void method() {     System.out.println( a + b );
  }
}
  1. Die println() Methode kann nicht ohne einen String Parameter benutzt werden.
  2. Da die Variable a privat ist, hat keine Klasse außer First Zugriff auf die Variable.
  3. Second kann First nicht erweitern.
  4. final ist kein gültiges Schlüsselwort für eine Klasse.

Eine Klasse kann eine final Klasse nicht erweitern. Daher ist Antwort C korrekt. println() ist auf verschiedenen Parametern definiert, auch mit int. Ließe man final weg, so käme dann der Fehler vom privaten Attribut a. final ist natürlich ein gültiges Schlüsselwort für Klassen.

Frage

Folgende Klassen sind auf einem Dateisystem, welches Groß/Kleinschreibung unterscheidet unter Fred.java gesichert. Welches sind korrekte Klassendeklarationen? (Zwei Antworten.)

  1. public class Fred {
      public int x = 0;
      public Fred( int x ) {
        this.x = x;
      }
    }
  2. public class fred {
      public int x = 0;
      public fred( int x ) {
        this.x = x;
      }
    }
  3. public class Fred extends MyBaseClass, MyOtherBaseClass {
      public int x = 0;
      public Fred( int xval ) {
        x = xval;
      }
    }
  4. protected class Fred {
      private int x = 0;
      private Fred( int xval ) {
        x = xval;
      }
    }
  5. import java.awt.*;
    public class Fred extends Object {
      int x;
      private Fred( int xval ) {
        x = xval;
      }
    }

Antwort A ist korrekt, da die Klasse die gleiche Groß/Kleinschreibung wie der Dateiname besitzt. B ist falsch, die die Schreibweise immer übereinstimmen muss. In Java gibt es keine Mehrfachvererbung, daher ist C falsch. Heißt die Klasse Fred.java, so muss sie auch von außen sichtbar sein. Daher muss sie public sein. Währe die Klasse zusammen mit einer anderen öffentlichen Klasse in einer Datei, so wäre dies korrekt. Auch E ist korrekt. Das Abstract Window Toolkit gehört zum Kern Paket von Java, ist also immer vorhanden. Obwohl jedes Objekt implizit Object erweitert, kann man dies noch einmal hinschreiben. Wenn der Konstruktor privat ist, lässt er sich nicht von außen aufrufen. So macht also diese Klasse wenig Sinn, da man sie nicht erzeugen kann. Man macht oft den Standard-Konstruktor private, wenn man den Benutzer zwingen will, einen parametrisieren zu verwenden.

Frage

Was passiert, wenn versucht wird, den folgenden Programmcode zu kompilieren und auszuführen?

class Mystery {
  String s;
  public static void main( Sting args[] ) {
    Mystery m = new Mystery();
    m.go();
  }
  void Mystery()
  {
    s = "palümpalüm";
  }
  void go()
  {
    System.out.println( s );
  }
}
  1. Dieser Code lässt sich nicht kompilieren.
  2. Dieser Code kompiliert, aber wirft eine Exception zur Laufzeit .
  3. Dieser Code läuft aber nichts erscheint in der Standard Ausgabe.
  4. Dieser Code läuft und schreibt "palümpalüm" in die Standard Ausgabe.
  5. Dieser Code läuft und schreibt "null" in die Standardausgabe.

Der Programmcode lässt sich nicht kompilieren, da die Methode Mystery() so heißt wie die Klasse. Da nur Konstruktoren so heißen dürfen wie die Klasse, Konstruktoren aber keine Rückgabewerte haben (sie geben explizit den this Zeiger des neuen Objektes zurück) muss man void von der Deklaration nehmen, so dass die Kompilation erfolgreich ist. So ist A korrekt. Wäre das void nicht vor dem Konstruktor würde das Programm palümpalüm ausgeben.

Frage

Welche der folgenden inneren Klassen sind korrekt für die Klasse A?

  1. class B { }
  2. class B extends A { }
  3. class B {
      B() {     System.out.println( "i = " + i );
      }
    }
  4. class B {
      class A { }
    }
  5. class A {
    }

Antwort A, B sind richtig. Antwort C ist falsch, da kein i deklariert wurde. D und E führen den Jikes Compiler an seine Grenzen.

Frage

Warum lassen sich die folgenden Klassen nicht kompilieren?

class A
{   private int x;
  public static void main( String args[] ) {
    new B();
  }
  class B {
    B() {       System.out.println( x );
    }   }
}
  1. Die Klasse B versucht, Zugriff zu der privaten Variablen zu bekommen, die in der äußeren Klasse definiert ist.
  2. Die Klasse A versucht, eine Instanz von B zu erzeugen, obwohl es keine gültige Instanz der Klasse A gibt.
  3. Der Konstruktor der Klasse B muss öffentlich sein.

Eine innere Klasse ist immer mit einer äußeren Klasse verbunden. Da aber eine static Method nicht an ein Objekt gebunden ist, wurde versucht ein B Objekt ohne Bezug zu einem A Objekt zu erzeugen. Dies ergibt die Fehlermeldung. So ist B korrekt. Folgende Zeilen würde die main() Funktion korrigieren.

public static void main( String args[] ) {

A a = new A();

A.B b = a.new B();

}

Frage

Was produziert das folgende Programm:

public class Test {
  static int total = 10;
  public static void main (String args []) {
    new Test();
  }
  public Test() {
    System.out.println( "In Test" );
    System.out.println( this );
    int temp = this.total;
    if ( temp > 5 )
      System.out.println( temp );
  }
}
  1. Die Klasse lässt sich nicht kompilieren.
  2. Der Compiler meldet einen Fehler in Zeile 2.
  3. Der Compiler meldet einen Fehler in Zeile 9.
  4. Der Wert 10 ist unter der Ausgabe.
  5. Die Klasse wird kompiliert, erzeugt jedoch einen Laufzeitfehler.

Die Klasse lässt sich kompilieren. Daher sind die Antworten A, B und C falsch. Die main() Methode erzeugt ein Test Objekt und dabei wird der Konstruktor aufgerufen. Dieser gibt erst "In Test" aus und anschließend den Hash Wert des Objektes. Da temp größer 5 ist, wird die Verzweigung genommen und 10 auf dem Schirm ausgegeben.

Frage

Was erfolgt, wenn man folgenden Progammcode kompiliert und ausführt.

abstract class Base {
  abstract void method(); 
  static int i;
}

public class Mine extends Base
{
  public static void main( String args[] ) {
  int[] a = new int[5];
  for( i = 0; i < a.length; i++ )
    System.out.println( a[i] );
  }
}
  1. Es werden  fünf Nullen ausgegeben.
  2. Das Feld a wird benutzt, bevor es initialisiert wurde.
  3. Kompilierfehler. Mine muss abstakt definiert werden.
  4. IndexOutOfBoundes Error i.

Abstrakte Klasse können Objekt- und Klassenvariablen besitzen sowie ausprogrammierte und wieder abstrakte Methoden. Erweitert eine Funktion eine abstrakte Klasse, so muss sie alle nicht ausprogrammierten Methoden implementieren, sonst ist diese Klasse wieder abstrakt. Mine erweitert zwar Base, überschreibt jedoch nicht die abstrakte Methode method(). Daher meldet der Compiler einen Fehler. So ist Antwort C korrekt und die anderen falsch.

Frage

Was passiert, wenn man folgendes Programm kompiliert und laufen lässt?

1: class Base {}
2: class Sub extends Base {}
3: class Sub2 extends Base {}
4:
5: public class Super {
6:   public static void main( String args[] ) {
7:     Base b = new Base();
8:     Sub s = (Sub) b;
9:   }
A: }
  1. Das Programm kompiliert und läuft ohne Fehler.
  2. Das Programm kompiliert nicht.
  3. Das Programm kompiliert aber liefert einen Fehler zur Laufzeit.

Die Definition aller vier Klassen ist korrekt und führt zu keinem Compilerfehler. Sub2 wird nicht benötigt und dient der Verwirrung. Die main() Methode legt eine lokale Variable b an. Diese Variable ist die Basisklasse von Sub. In Zeile 8 versuchen wir aber diese einfache Klasse über die explizite Typumwandlung zur Klasse Sub aufzubauen. Dies lässt der Compiler durch,  aber da Base einfach kein Sub werden kann, führt die Ausführung zu einem Laufzeitfehler. Ohne die Typumwandlung würde es schon zu einem Compilerfehler kommen. Daher ist Antwort C alleine korrekt.

Frage

Welche Modifier lassen sich im Programmcode für die innere Klasse korrekt einsetzen?

public class Clazz {
  public static void main( String args[] ) { }
  
  /* Modifier */ class MyInner { }
}
  1. public
  2. private
  3. static
  4. friend

public, private, static sind mögliche Modifier für innere Klassen. Also ist A, B und C korrekt. Es ist Eigenheit der Sprache C++ Freunde zu definieren, friend ist in Java kein eingetragenes Schlüsselwort.

Ähnliche Beiträge

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert