q1:java-oop2

Konstruktoren, Klassenvariablen und –methoden

Eine Konstruktor-Methode oder auch nur Konstruktor ist eine besondere Methodenart, die beim Erstellen eines Objekts aufgerufen wird - mit anderen Worten, wenn ein Objekt konstruiert wird. Im Gegensatz zu anderen Methoden kann man einen Konstruktor nicht direkt aufrufen. Wenn mit „new“ ein neues Objekt der Klasse erstellt wird, führt Java drei Aktionen aus:

  • Zuweisung von Speicherplatz für das Objekt
  • Initialisierung der Objektvariablen des Objekts auf ihre Anfangswerte oder auf einen Standard (0 bei Zahlen, NULL bei Objekten, false bei booleschen Werten sowie '\0' bei Zeichen)
  • Aufruf des Konstruktors der Klasse (die eine von mehreren Methoden sein kann)

Wenn in der Deklaration der Klasse kein expliziter Konstruktor definiert ist, wird ein Standardkonstruktor aufgerufen (hinter dem Schlüsselwort „new“):

GiroKonto meinKonto = new GiroKonto() Klassenname Objektname Aufruf des Konstruktors

Durch explizites Definieren von Konstruktoren in Ihren Klassen können diese z.B. Attributwerte von Objekten setzen, Methoden anhand dieser Variablen oder Methoden anderer Objekte aufrufen und die anfänglichen Eigenschaften Ihres Objekts bestimmen.

Konstruktoren sehen zunächst wie normale Methoden aus, unterscheiden sich von diesen aber in drei Punkten:

  • Konstruktoren haben immer den gleichen Namen wie die Klasse.
  • Konstruktoren haben keinen Rückgabetyp.
  • Konstruktoren können in der Methode keinen Wert durch die Verwendung des Ausdrucks return zurückgeben

Das folgende Beispiel ist eine Neufassung des Kontobeispiels aus Kapitel 10, aber diesmal mit einem Konstruktor, der auch die Aufgabe der Initialisierung der Attribute übernimmt:

public class GirokontoN 
// Modifizierte Klasse Girokonto mit Konstruktor und Klassenvariable
{
   private double Kontostand;      // Zuerst die beiden Attribute der Klasse
   private double Kredit;
   private long KontoNr;
   static long KontoNr_Zaehler = 1;
 
   GirokontoN(double dispo)  // Konstruktor, übergeben wird der Kreditrahmen
   {
     Kontostand = 0; 
     Kredit = dispo;
     KontoNr = KontoNr_Zaehler;
     KontoNr_Zaehler++ ;
   }
 
   public double KontostandAnzeigen() // Methode
 
// ab hier weiter wie im Programm in Kapitel 18

Neben dem Konstruktor findet sich als weitere Neuerung eine so genannte Klassenvariable. Darunter versteht man eine Variable, die es nur einmal innerhalb einer Klasse gibt, egal wie viel Objekte dieser Klasse angelegt werden.

Betrachten wir zunächst einmal ein normales Attribut wie Kontostand. Diese Variable hat für jedes Objekt von GirokontoN einen eigenen Attributwert, besser jedes Objekt hat seine eigene Variable, deren Wert völlig unabhängig vom Wert in anderen Objekten ist.

Das Attribut KontoNr_Zaehler ist hingegen die Klassenvariable. Sie besitzt in allen Objekten von GirokontoN denselben Wert. Es gibt sie also nur einmal, egal wie viele Objekte von GirokontoN geschaffen werden. Man erkennt eine Klassenvariable immer am Schlüsselwort static.

Dies ist eine gute Anwendung für eine Klassenvariable, denn jedes Konto, also jedes Objekt der Klasse GirokontoN, soll natürlich seine eigene Kontonummer haben. Dazu braucht man aber eine Information darüber, welche Kontonummern schon vergeben sind. Dazu dient die Klassen-variable KontoNr_Zaehler. Sie erhält in der Definition der Klasse den Anfangswert 1. Schafft man ein Objekt von GiroKontoN, dann erhält dieses durch den Konstruktor als Attribut KontoNr den Wert 1 und die Klassenvariable KontoNr_Zaehler wird um 1 erhöht. Beim Schaffen des nächsten Objekts wird KontoNr in diesem Objekt 2 und die Klassenvariable wieder um 1 erhöht. So stellt man sicher, dass alle Objekte der Klasse fortlaufende Konto¬nummern erhalten.

Übrigens, die normalen Attribute der Klasse, zur Abgrenzung von Klassenvariablen auch gerne als Objektvariablen bezeichnet, wurden hier mit dem Schlüsselwort private versehen. Dadurch wird erreicht, dass man von außerhalb der Klasse, z.B. in einem Hauptprogramm, das ein- oder mehrere Objekte der Klasse verwendet, nicht mehr unmittelbar auf die Attribute zugreifen

kann, d.h. Aufrufe wie kontostand+=10000; sind nicht mehr möglich. Man soll nur noch über Methoden wie GeldEinzahlen() die Attributwerte ändern können. Diese Sicherheitsmaß-nahme bezeichnet man als Datenkapselung.

Hier jetzt ein mögliches Hauptprogramm zur Klasse GirokontoN:

// Anfang Ereignisprozeduren
  public void btnStartActionPerformed(ActionEvent evt)
  {
     //Anlegen von Objekten der Klassen GirokontoN:
     GirokontoN sierakowskyKonto = new GirokontoN(3000);
     GirokontoN schaeferKonto = new GirokontoN(1000);
     GirokontoN lächaKonto = new GirokontoN(0);
     // "LächaKonto.Kontostand += 10000;"  funktioniert nicht, wie man leicht
     //  testet, da Kontostand als private deklariert wurde.
 
     //Transaktionen:
     sierakowskyKonto.GeldEinzahlen(10000);
     schaeferKonto.GeldAbheben(700);
     lächaKonto.GeldEinzahlen(250);
 
     //Ausgabe:
     tAAusgabe.append("Sierakowsky:\n");
     tAAusgabe.append("Kontonummer: " +  
		String.valueOf(sierakowskyKonto.KontoNrAnzeigen()) + "\n");
     tAAusgabe.append("Kontostand: " + 
		String.valueOf(sierakowskyKonto.KontostandAnzeigen()) + "\n\n");
 
     tAAusgabe.append("Schaefer:\n");
     tAAusgabe.append("Kontonummer: " + 
		String.valueOf(schaeferKonto.KontoNrAnzeigen()) + "\n");
     tAAusgabe.append("Kontostand: " + 
		String.valueOf(schaeferKonto.KontostandAnzeigen()) + "\n\n");
 
     tAAusgabe.append("Lächa:\n");
     tAAusgabe.append("Kontonummer: " + 
		String.valueOf(lächaKonto.KontoNrAnzeigen()) + "\n");
     tAAusgabe.append("Kontostand: " + 
		String.valueOf(lächaKonto.KontostandAnzeigen()) + "\n\n");
  }
  // Ende Ereignisprozeduren

Aufgaben

Teste das oben angegebene Programm mit verschiedenen Konten und Transaktionen!

Erläutere an den folgenden Quelltexten die Begriffe „Klasse“, „Objekt“, „Attribut“, „Methode“ und „Konstruktor“ in der Form „knappe Definition“-„konkretes Beispiel“:

public class Hauptprogramm 
//Es handelt sich um eine Konsolenanwendung ohne grafische Oberfläche
{
  public static void main(String[] args)
  {
      Buch winnetou = new Buch(1871,false,"Winnetou 1", "May, Karl",23.95);
      Buch java2 = new Buch(2001,true,"Java 2", "Lemay, Laura", 49.00);
      java2.druckeDaten();
      winnetou.druckeDaten();
  }
}
public class Buch
{
  String buchtitel;
  String autor;
  long erscheinungsjahr;
  boolean sachbuch;
  double preis;
 
  Buch(long ej, boolean sb, String tit, String aut, double pr)
  {
    buchtitel = tit;
    autor = aut;
    erscheinungsjahr = ej;
    sachbuch = sb;
    preis = pr;
  }
 
  public void druckeDaten()
  {
    System.out.println("Titel: " + buchtitel);
    System.out.println("Autor: " + autor);
    System.out.println("Sachbuch: " + sachbuch);
        if (sachbuch == true)
        System.out.println("Das Buch ist ein Sachbuch.");
    else
        System.out.println("Das Buch ist Belletristik.");
    System.out.println("Erscheinungsjahr: " + erscheinungsjahr);
  }
}

Was ist der Unterschied zwischen einer Klassen- und einer Objektvariablen? Erläutere das an zwei Beispielen.

Was versteht man unter Datenkapselung? Erläutere den Begriff an den zwei Beispielen.

Betrachte folgende Quelltexte:

Schüler HansBambel = new Schüler("Bambel","Hans",5);
  Schüler SusiSonnenschein = new Schüler("Sonnenschein","Susi",7);
 
  // Anfang Ereignisprozeduren
  public void btnStartActionPerformed(ActionEvent evt)
  {
     HansBambel.versetzen(4.1);
     tAAusgabe.append("Hans: "+Integer.toString(HansBambel.getJahrgangsstufe())+"\n");
 
     SusiSonnenschein.versetzen(1.9);
     tAAusgabe.append("Susi: "+Integer.toString(SusiSonnenschein.getJahrgangsstufe()));
  }
 
  // Ende Ereignisprozeduren
 
public class Schüler
{
   private String Name;
   private String Vorname;
   private int Jahrgangsstufe;
   private long SNr;
   static long SNrZähler = 1;
   private boolean istMaedchen ;
 
   Schüler(String n, String vn, int jg)
   {
      Name = n;
      Vorname = vn;
      Jahrgangsstufe = jg;
      SNr = SNrZähler;
      SNrZähler++;
   }
 
   public String getName()
   {
     return Name;
   }
 
   public int getJahrgangsstufe()
   {
     return Jahrgangsstufe;
   }
 
   public void versetzen(double Notenschnitt)
   {
     if(Notenschnitt <= 4.0)
       Jahrgangsstufe++;
   }
}
  1. An welchen Stellen taucht hier Datenkapselung auf? Hätte man darauf verzichten sollen?
  2. Was passiert, wenn man den Befehl HansBambel.Jahrgangsstufe++ ins Hauptprogramm schreibt? Kommentiere das Verhalten!
  3. Erläutere den Konstruktor zeilenweise! Ergänze ihn so, dass das Geschlecht bereits beim Erzeugen der Schüler-Objekte angegeben werden muss und verändere auch das Hauptprogramm entsprechend!
  4. Schreibe eine Methode, die die Schülernummer SNr zurückliefert!
  5. Erstelle zum Schluss ein UML-Diagramm der Schüler-Klasse!

Erstelle eine Klasse „Bruch“ mit den Attributen „Zähler“ und „Nenner“, einen Konstruktor sowie die Methoden getZähler(), getNenner(), multiplizieren(), kürzen(), erweitern(), istGleich() (einem anderen Bruch), addieren() (einen anderen Bruch), subtrahieren(), dividieren(). Entwickle ein passendes Hauptprogramm „Bruchrechner“ und teste damit die korrekte Funktionsweise der Klasse!

(aus einer GK-Arbeit) Betrachte die folgenden Java-Programme:

public class Konto
{
  String Inhaber;
  long Kontonummer;
  boolean Onlinekonto;
  double Kontostand = 0;
  double Dispositionskredit;
 
  Konto(String Inhaber, long Kontonummer, boolean Onlinekonto, int    
        Dispositionskredit)
  {
    this.Inhaber = Inhaber;
    this.Kontonummer = Kontonummer;
    this.Onlinekonto = Onlinekonto;
    this.Dispositionskredit = Dispositionskredit;
  }
  public void drucken()
  {
    System.out.println("Kontonummer: " + Kontonummer);
    System.out.println("Kontoinhaber: " + Inhaber);
    System.out.println("Kontostand: " + Kontostand);
    System.out.println("Dispo: " + Dispositionskredit);
    if(Onlinekonto == true)
    {
      System.out.println("Es handelt sich um ein Onlinekonto");
    }
    else
    {
      System.out.println("Es handelt sich um ein herkömmliches Konto");
    }
  }
}
public class Start 
{
  public static void main(String[] args)
  {
    Konto Konto1 = new Konto("Hans Bambel",4711,false,0);
    Konto Konto2 = new Konto("James Bond",7,true,2000000);
 
    Konto2.drucken();
  }
}
  1. Definiere die Begriffe Klasse, Objekt, Attribut, Attributwert und Methode jeweils in einem Satz und gib immer ein konkretes Beispiel aus dem Quelltext an!
  2. Gib die Bildschirmausgabe des Hauptprogramms Zeile für Zeile an!
  3. Was bedeuten die Schlüsselwörter void und this?
  4. Ergänze das Programm um folgende Methoden:
  • Die Methode Kontostand soll den aktuellen Kontostand zurückgeben.
  • Die Methode einzahlen soll einen übergebenen Betrag auf das Konto buchen.
  • Die Methode abbuchen soll überprüfen, ob der übergebene Betrag ohne Überschreiten des Dispositionskredites abgebucht werden kann. Falls ja, soll das Geld abgebucht werden, sonst soll nur eine Fehlermeldung ausgegeben werden. Die Methode verzinsen soll das Konto mit dem übergebenen Zinssatz verzinsen.

Erstelle eine Klasse „Punkt“ mit den Attributen xKoordinate und yKoordinate. Schreibe einen Konstruktor, der die Koordinaten des Punktes erhält, sowie die Methoden

  • getx() gibt den x-Wert des Punktes zurück
  • gety() gibt den y-Wert des Punktes zurück
  • verschiebe() schiebt den Punkt um die übergebenen Werte a in x-Richtung und b in y-Richtung
  • getQuadrant() gibt den Quadranten (1,2,3,4) zurück. Welches Problem tritt dabei auf und wie löst du es?
  • getAbstand() gibt den Abstand des Punktes vom Ursprung zurück.

Schreibe ein Hauptprogramm, das die Punkte Dieter(5/3) und Hans(2/-5) erzeugt und dann Dieter 7 nach links und 2 nach oben verschiebt, dann den Quadranten von Dieter und den Abstand von Hans zum Ursprung auf den Bildschirm schreibt. Zuletzt sollen die Koordinaten von Dieter in der Form x/y auf den Bildschirm geschrieben werden.

  • /var/www/infowiki/data/pages/q1/java-oop2.txt
  • Zuletzt geändert: 2017/07/11 10:31
  • von admin03