Objektorientierte Programmierung OOP

KE3 Klassen, Objekte und Felder; Begriffe, Beispiele und Definitionen

KE3 Klassen, Objekte und Felder; Begriffe, Beispiele und Definitionen


S. H.
Diese Lernkarten bieten einen umfassenden Überblick über die Grundlagen der objektorientierten Programmierung (OOP) auf Universitätsniveau. Sie konzentrieren sich auf zentrale Konzepte wie Methoden, Objekte, Variablen und Klassen, wobei auch spezifische Themen wie Felder, Typen und Konstruktoren behandelt werden. Die Karteikarten eignen sich besonders für Studierende der Informatik, die ihr Verständnis von OOP vertiefen möchten, indem sie praktische Beispiele und Definitionen nutzen, um die theoretischen Grundlagen zu veranschaulichen.
Flashcards
75
Students
2
Language
German
Category
Computer Science
Level
University
Created / Updated
23.02.2013 / 16.05.2022

Flashcards

Beispiel: return-Anweisung

Wollen wir nun eine Methode liefereRabatt() implementieren so muss diese den aktuellen Wert des Attributs rabatt zurückliefern.

class Rechnung {

   // Attribute

   double betrag;

   double mehrwertsteuer;

   double rabatt;

   Kunde rechnungsempfaenger;

   // Methoden

   double liefereRabatt() {

      return this.rabatt;

    }

}

Bemerkung: return-Anweisung in einer Methode ohne Ergebnistyp  

Eine return-Anweisung in einer Methode ohne Ergebnistyp liefert keinen Wert an den Aufrufer zurück, sie ermöglicht aber, zum Beispiel im Falle von ungültigen Argumenten, die Methode vorzeitig zu beenden. Am Ende jeder Methode ohne Ergebnistyp steht implizit eine return-Anweisung.

Bemerkung: return-Anweisungen einer Methode mit Ergebnistyp  

In einer Methode mit Ergebnistyp muss am Ende jedes möglichen Ablaufpfades eine return-Anweisung mit einem passenden Ausdruck stehen.

Bemerkung: Getter- und Setter-Methoden  

In den meisten Klassen haben wir Methoden, die das Auslesen und Verändern von Attributen ermöglichen, wie zum Beispiel die Methoden legeRabattFest(final double neuerRabatt) und liefereRabatt(). Im Englischen wählt man für solche Methoden in der Regel Namen wie getDiscount() und setDiscount(final double newDiscount). Deswegen werden diese Methoden auch als Getter- und SetterMethoden bezeichnet.

Begriff: Aufruf mit Wertübergabe (engl. call by value)

Wird als Parameter ein Wert eines primitiven Datentyps übergeben, so hat die weitere Verarbeitung dieses Wertes durch die Methode keinerlei Auswirkungen auf die aufrufende Stelle. In diesem Fall spricht man von einem Aufruf mit Wertübergabe (engl. call by value).

Begriff: Aufruf mit Referenz (engl. call by reference)

Wird einer Methode als Parameter ein Objekt übergeben, so handelt es sich, exakt gesprochen, um eine Referenz auf das Objekt. Sofern weitere Referenzen auf dieses Objekt existieren, was in der Regel zumindest an der aufrufenden Stelle der Fall ist, sind Veränderungen des Objekts an allen Referenzen gleichermaßen bemerkbar. Dies wird als Aufruf mit Verweisübergabe (engl. call by reference) bezeichnet.

 

Wird dem Parameter eine andere Referenz zugewiesen, so hat dies keine Auswirkung auf den Aufrufer.

Aufgabe: Was sind Konstruktoren?

Konstruktoren (engl. constructor) sind spezielle Methoden, um Exemplare einer Klasse zu erzeugen. Konstruktoren sind immer nach derjenigen Klasse benannt, deren Exemplare sie erzeugen. In ihnen werden in der Regel die nötigen Initialisierungen, zum Beispiel die Belegung der Attribute mit Anfangswerten, durchgeführt. Es handelt sich bei einem Konstruktor um eine besondere Methode, die immer das eben erzeugte Objekt zurückliefert. Ein Konstruktor wird nie an einem Objekt oder einer Klasse aufgerufen sondern immer in Zusammenhang mit dem Schlüsselwort new.

Definition: Konstruktordeklaration  

Eine Konstruktordeklaration besteht aus einem Kopf und einem Rumpf. Sie genügt folgender Form:

Konstruktorname(Parameterliste) {

    Anweisungen

}

Der Name des Konstruktors muss mit dem Namen der Klasse, der er angehört, identisch sein. Anders als bei einer Methodendeklaration hat eine Konstruktordeklaration keinen expliziten Ergebnistyp und der Rumpf muss keine return-Anweisung enthalten. [JLS: § 8.8]

Definition: Signatur eines Konstruktors  

Die Signatur eines Konstruktors besteht aus dem Konstruktornamen sowie den Typen seiner formalen Parameter. [JLS: § 8.8.2]

 

Konstruktorennamen können ebenso wie Methodennamen überladen werden. [JLS: § 8.8.8]

Bemerkung: finale Attribute

Finale Attribute müssen entweder direkt bei der Deklaration initialisiert werden, oder in allen Konstruktoren der Klasse. Anderenfalls entsteht ein Übersetzungsfehler. So können wir unsere Rechnung beispielsweise mit einer Rechnungsnummer versehen, die im Konstruktor gesetzt wird und sich später nicht mehr verändern darf. Wir übergeben die Rechnungsnummer als Parameter. Eine weitere Zuweisung im gleichen Konstruktor oder in einer Methode würde zu einem Übersetzungsfehler führen.

class Rechnung {

   // Attribute

   double betrag;

   double mehrwertsteuer;

   double rabatt;

   Kunde rechnungsempfaenger;

   final int rechnungsnummer;

   // Konstruktoren

   Rechnung(final int rechnungsnummer) {

      this.rechnungsnummer = rechnungsnummer;

    }

}

Beispiel: Konstruktor aufruf im Konstrukter

class Rechnung {

   // Attribute

   double betrag;

   double mehrwertsteuer;

   double rabatt;

   Kunde rechnungsempfaenger;

   final int rechnungsnummer;

   // Konstruktoren

   Rechnung(final int rechnungsnummer) {

      this(rechnungsnummer, 0.19);

   }

   Rechnung(final int rechnungsnummer, final double       

            mwst) {

      this.rechnungsnummer = rechnungsnummer;

      this.mehrwertsteuer = mwst;

    }

}

Bemerkung: Initialisierung der Exemplarvariablen  

Die Exemplarvariablen werden vor der Ausführung des Konstruktors initialisiert.

Definition: Klassenvariable  

Eine Klassenvariable wird durch das Schlüsselwort static, das der Attributvereinbarung vorangestellt wird, nach folgendem Muster deklariert [JLS: § 8.3.1.1]:

static Typ Name;

 

Bemerkung: Klassenvariablen werden auch als Klassenattribute bezeichnet. Um keine Verwir- Klassenattribut rung entstehen zu lassen, können Exemplarvariablen dann auch als Exemplarattribute bezeichnet werden.

Java-Konventionen: Aufruf und deklaration von Klassenattributen

Erfolgt ein Zugriff auf eine Klassenvariable von innerhalb der Klasse, stellt man den Klassennamen zur Verdeutlichung auch voran. In der Klassendeklaration werden in der Regel erst die Klassenvariablen und anschließend die Exemplarvariablen deklariert

Beispiel: Zugriff auf Klassenattribute

class Rechnung {

   // Klassenattribute

   static int naechsteRechnungsnummer = 10000;

   // Exemplarattribute

   double betrag;

   double mehrwertsteuer;

   double rabatt;

   Kunde rechnungsempfaenger;

   final int rechnungsnummer;

   // Konstruktoren

   Rechnung() {

      this(0.19);

   }

   Rechnung(double mwst) {

      this.mehrwertsteuer = mwst;

      this.rechnungsnummer =

      Rechnung.naechsteRechnungsnummer;

      Rechnung.naechsteRechnungsnummer++;

    }

}

Beispiel: Konstanten als Klassenattributen

class Rechnung {

   // Klassenattribute

   static final double

   STANDARD_MEHRWERTSTEUERSATZ = 0.19;

   static int naechsteRechnungsnummer = 10000;

   // Exemplarattribute

   double betrag;

   double mehrwertsteuer;

   double rabatt;

   Kunde rechnungsempfaenger;

   final int rechnungsnummer;

   // Konstruktoren

   Rechnung() {

      this(Rechnung.STANDARD_MEHRWERTSTEUER

      SATZ);

   }

   Rechnung(double mwst) {

      this.mehrwertsteuer = mwst;

      this.rechnungsnummer =

      Rechnung.naechsteRechnungsnummer;

      Rechnung.naechsteRechnungsnummer++;

    }

}

Für die Bezeichner von finalen Klassenattributen gelten die Konventionen finaler lokaler Variablen.

Definition: Klassenmethode  

Klassenmethoden werden wie Methoden vereinbart, mit dem Unterschied, dass ihnen das Schlüsselwort static vorangestellt ist. [JLS: § 8.4.3.2]

Definition: Vereinbarung von Feldern

Eine Variable für ein Feld wird wie folgt vereinbart:  

ElementTyp[] Feldname;  

Der Feldtyp ist durch den Datentyp der Elemente (ElementTyp), die in einem Feld enthalten sind, bestimmt.

Beispiel: Deklaration einer Feldvariable  

Die Deklaration

int[] artikelnummern;

bezeichnet ein Feld mit Elementen vom Typ int, das artikelnummern genannt wird.

Bemerkung: Feldtypen sind Objekttypen. Jedes Feld ist somit auch ein Objekt. [JLS: § 4.3.1]

Definition: Erzeugung eines Felds  

Einem Feldnamen wird ähnlich wie bei Objekten mittels Schlüsselworts new ein Feldobjekt fester Größe zugewiesen:

Feldname = new ElementTyp[IntAusdruck];

Mit dem Ausdruck auf der rechten Seite der Zuweisung wird ein konkretes Feld mit Elementen des Typs ElementTyp der Größe IntAusdruck angelegt. Die Feldgröße wird durch einen Ganzzahlausdruck bestimmt. Der Ausdruch muss zu einem nichtnegativen Wert evaluiert werden. Die Referenz auf das erzeugte Feld wird der Feldvariablen Feldname, die vom gleichen Typ sein muss, zugewiesen. Die Feldelemente sind von 0 bis IntAusdruck - 1 indiziert. [JLS: § 10.3, § 15.10]

Definition: Vereinbarung und Erzeugung eines Felds  

Es ist auch möglich, die Variablenvereinbarung und Felderzeugung zu kombinieren [JLS: § 10.2]:

ElementTyp[] Feldname = new ElementTyp[IntAusdruck];

Statt das Schlüsselwort new zu verwenden, kann ein Feld auch durch eine Aufzählung gebildet und zugleich initialisiert werden [JLS: § 10.6]:  

ElementTyp[] Feldname = {v1, v2, ..., vn};

Die Ausdrücke v1, v2, ..., vN müssen Werte des Typs ElementTyp liefern.

Beispiel: Erzeugung eines Felds

Der Ausdruck:

int[] artikelnummern = new int[10];

erzeugt ein Feld mit 10 Elementen vom Typ int und weist es der Feldvariablen artikelnummern zu.

 

Beispiel: Erzeugung und Initialisierung eines Felds  

Das Feld deutscheVokale gibt ein Beispiel für die Aufzählungsdefinition eines Felds:

char[] deutscheVokale = {’a’, ’ä’, ’o’, ’ö’, ’u’, ’ü’, ’e’, ’i’};

Bemerkung: Initialisierung eines Felds  

Eine solche Aufzählung kann in dieser Form nur bei der Deklaration verwendet werden. Soll sie auch an anderer Stelle genutzt werden, so müssen der Aufzählung der Feldelemente, das Schlüsselwort new und der Feldtyp vorangestellt werden.

char[] deutscheVokale;

// ...

deutscheVokale = new char[]{’a’, ’ä’, ’o’, ’ö’, ’u’, ’ü’, ’e’, ’i’};

Definition: Länge eines Felds  

Jedes Feld besitzt eine finale Exemplarvariable length. Die Größe eines Felds Feldname kann somit im Programm durch den ganzzahligen Ausdruck:

Feldname.length

ermittelt werden. [JLS: § 10.7]

Beispiel: Länge eines eindimensionalen Felds

So liefert beispielsweise der Ausdruck deutscheVokale.length; den Wert 8, wenn die Variable deutscheVokalewie oben dargestellt initialisiert wurde.

Bemerkung: Standardbelegung der Feldelemente  

Falls ein Feld aus Elementen primitiver Datentypen aufgebaut ist, wird jedes Feldelement mit dem Standardwert dieses Typs belegt. Für ein Ganzzahlfeld ist der Standardwert 0, für Gleitkommazahlen der Wert 0.0, für Zeichenelemente das Zeichen mit dem Ganzzahlcode 0, und für boolean ist es der Wert false. Handelt es sich bei dem Typ der Feldelemente um einen Objekttyp, so sind alle Elemente mit null initialisiert. [JLS: § 15.10.1, § 4,12.5]

Definition: Feldzugriff  

Die Werte der Elemente eines Feldes können durch den vordefinierten Indexausdruck: Feldname[IntAusdruck] abgefragt oder verändert werden. Der Indexausdruck muss ein ganzzahliger Wert sein. [JLS: § 10.4]

Bemerkung: Feldindex  

Feldindizes beginnen immer mit 0. Daher dürfen Indexausdrücke in Feldzugriffen weder negative ganze Zahlen sein, noch dürfen sie den größten Indexwert Feldname.length - 1 überschreiten. Falls der int-Ausdruck, der den Index bestimmt, außerhalb der Feldgrenzen 0 bis Feldname.length - 1 liegt, wird dieser Zugriff einen Laufzeitfehler erzeugen. [JLS: § 10.4]

Beispiel: Feldzugriff

Die obige Vereinbarung der Feldvariable deutscheVokale vorausgesetzt, ist der Ausdruck

deutscheVokale[3]

ein gültiger Zugriff und liefert das Ergebnis ö.

 

Bemerkung: Belegung eines Felds  

Die Elemente eines Felds können durch eine for-Schleife einheitlich mit Anfangswerten belegt werden:

for (int i = 0; i < Feldname.length; i++) {

    Feldname[i] = Wert;

}

wobei Wert verträglich mit dem den Typ der Feldelemente sein muss.

Bemerkung: finale Feldvariablen  

Beachten Sie, dass eine als final deklarierte Feldvariable lediglich keine neue Zuweisung an diese Variable zulässt. Eine Veränderung der Feldinhalte ist jedoch trotzdem möglich.

Definition: Erweiterte for-Schleife  

Die erweiterte for-Schleife besitzt die folgende Syntax:

for (ElementTyp VarName : Feldname) {

// ...

}

wobei der Typ ElementTyp mit dem Typ der Elemente des Feldes Feldname verträglich sein muss. [JLS: § 14.14.2]

Beispiel: mehrdimensionalen Feldern mit der erweiterten For-Schleife

int[][] meinFeld = new int[4][3];

for (int[] x : meinFeld) {

    for (int y : x) {

        // y ist das aktuelle Feldelement

    }

}

Bemerkung: mehrdimensionale Felder mit erweiterten For-Schleife

Im Gegensatz zu der einfachen for-Schleife gibt es bei dieser Form jedoch keine Variable, die den aktuellen Index im Feld repräsentiert. Somit ist es ohne weitere Hilfsvariable auch nicht möglich zwei Felder parallel zu durchlaufen. Zudem ermöglicht die erweiterte for-Schleife nur einen lesenden Zugriff auf die Feldelemente und somit keine Veränderung der Feldinhalte.

Study