Klassen in Java: Die Grundlagen der objektorientierten Programmierung


In der Programmiersprache Java besitzen Klassen eine sehr große Bedeutung. Sie sind die Baupläne nach denen Objekte (Instanzen von Klassen) modelliert werden. Wir behandeln in diesem Beitrag die wichtigsten Eigenschaften vom Klassen in Java.

Dabei soll dieser allgemeine Beitrag über Klassen und Methoden als Übersicht dienen. Ausführliche Erklärungen zu den einzelnen Themen findet ihr in den jeweiligen Themenbeitrag:

Was ist objektorientierte Programmierung?

Objektorientierte Programmierung ermöglicht eine natürliche Modellierung, erhöht die Effizienz des Entwicklers durch Wiederverwendbarkeit der Programmelemente und vermindert die Komplexität der Anwendungen durch Abstraktion und Kapselung.

Durch Abstraktion wird zwischen Konzept und Umsetzung unterschieden, d.h. es gibt ein Objekt und einen Bauplan nach dem dieses Objekt modelliert wird. Klassen sind Baupläne nach denen Objekte modelliert werden.

Die fünf Konzepte der objektorientierten Programmierung in Java sind:

Aufbau einer Klasse in Java

Schauen wir uns zunächst einmal den Aufbau einer einfachen Klasse in Java an:

In dem oberen Quellcode-Beispiel ist die Klassendefinition der Klasse Schaf aufgeführt. Jede Klassendefinition beginnt mit dem class-Schlüsselwort. Die eigentliche Definition der Klasse, die Angabe der Variablen- und Methodendefinitionen, wird innerhalb der geschweiften Klammern vorgenommen.

Die Schaf-Klasse enthält keine Methoden und besteht nur aus den drei Variablen name, alter und wollMenge.

Die drei Variablen der Klasse Schaf werden als Attribute oder Instanzvariablen bezeichnet. Aber auch die Begriffe Membervariablen und Instanzmerkmale werden oft für sie verwendet. Eine ausführliche Beschreibung was eine Klasse in Java ist, findet ihr in unserem Beitrag: Klassen und Objekte (Instanzen von Klassen) in Java.

Methodendefinition – Definieren von Methoden in Java

Die Methodendefinition wird innerhalb der Klassendefinition vorgenommen. Die Methoden haben dadurch Zugriff auf alle Variablen des Objekts.

Die Syntax der Methodendefinition in Java ist sehr einfach:

In der Methodendefinition können mehrere Modifier angegeben werden.

An zweiter Stelle steht der Datentyp des Rückgabewerts der Methode. Diesem folgt der Methodenname und ein Klammernpaar, in dem sich die optionale Parameterliste befindet. Das Klammernpaar muss in jedem Fall angegeben werden, auch wenn eine leere Parameterliste verwendet wird.

Die Anweisungen, welche das Verhalten der Methode vorgeben, stehen im Methodenrumpf innerhalb der beiden geschweiften Klammern.

In Java spielen Methoden eine zentrale Rolle. Sie bestimmen das Verhalten von Objekten und somit auch das Verhalten des gesamten Programms. Wenn ihr mehr über Methoden erfahren wollt, ist unser Beitrag über Methoden in Java – Was sind Methoden und wie werden sie verwendet ein hervorragender Anfang.

Überladen von Methoden in Java

Der Java-Compiler vergibt jeder Methode eine eigene eindeutige Signatur. Dadurch ist es erlaubt innerhalb einer Klasse den gleichen Methodennamen für unterschiedliche Methoden zu verwenden.

Die Signatur der Methoden setzt sich aus dem nach außen sichtbaren Methodennamen und einer codierten Information über die Parameterliste der Methode zusammen. Die codierte Information über die Parameterliste enthält Angaben über die Datentypen der Methodenparameter und die Reihenfolge der Parameter.

Somit bekommt jede Methode in Java einen eigenen internen Namen zugewiesen. Dieser interne Methodenname muss immer eindeutig sein, daher sind Methoden mit gleichen äußeren Methodennamen und gleicher Parameterliste nicht erlaubt. Gleichnamige Methoden müssen sich also mindestens in einem Parameter unterscheiden.

Dieses Konzept, das mehrfache Verwenden des gleichen Methodennamens, wird als Überladen von Methoden bezeichnet.

Wann sollte man Methoden überladen?

Es ist immer dann empfehlenswert Methoden zu überladen, wenn die gleichnamigen Methoden nahezu identische Funktionen ausführen. Eine sinnvolle Anwendung für das Überladen von Methoden ist die Simulation von variablen Parameterlisten. In diesem Fall wäre die Funktionalität jeder gleichnamigen Methode identisch, die Methoden würden ihre Arbeit aber mit unterschiedlichen Parametern verrichten.

Mit einer variablen Parameterliste beliebig viele Argumente an Methoden übergeben

Bei der Entwicklung von Anwendungen ist es manchmal schwierig bereits im Vorfeld anzugeben wieviele Parameter zur Laufzeit für das Erfüllen einer bestimmten Funktionalität benötigt werden.

Diese Problematik wurde durch das Einführen der variablen Parameterliste in Java 5 gelöst. Seitdem können mit Hilfe der variablen Parameterliste beliebig viele Argumenten an eine Methode übergeben werden.

Dazu wird einfach der letzte Methodenparameter, durch Anfügen von drei Punkten, als variabel gekennzeichnet. Die drei Punkte müssen direkt nach dem Datentyp und vor dem Parameternamen stehen: int... parameter.

Wichtig! In Java darf nur der letzte Methodenparameter variabel sein, da sonst der Compiler nicht eindeutig die Argumente übergeben kann.

Die Syntax der variablen Parameterliste ist in folgendem Quelltextbeispiel dargestellt:

Die variable Parameterliste ist in Java als ein Array-Parameter implementiert, welcher aus den übergebenen Argumenten erstellt wird. Auf die Elemente dieses Arrays wird wie gewohnt zugegriffen.

Konstruktoren und Destruktoren in Java

In Java werden Konstruktoren und Destruktoren verwendet, um Objekte zu initialisieren bzw. zu zerstören (finalize).

Konstruktoren sind als Methoden ohne Rückgabewert in Java implementiert. Sie tragen den Namen ihrer Klasse. Es ist möglich in einer Klasse mehrere verschiedene Konstruktoren zu definieren. Diese müssen sich durch ihre Parameterliste unterscheiden und können wie Methoden überladen werden.

Die Syntax von Konstruktoren ist wie folgt:

Der Aufruf eines Konstruktors erfolgt immer mit Hilfe des new-Schlüsselworts gefolgt von dem Konstruktornamen. Der Konstruktor liefert automatisch eine Referenz auf das initialisierte Objekt zurück, obwohl der Konstruktor selbst keine return-Anweisung besitzt.

Ein Konstruktor kann auch mit einer Parameterliste wie eine Methode aufgerufen werden, dabei werden die Argumente in dem Klammernpaar nach dem Konstruktornamen angegeben.

Mit Modifiern in Java die Eigenschaften von Variablen, Methoden und Klassen verändern

Java Modifier

Modifier werden in Java-Anwendungen benutzt um die Sichtbarkeit, Lebensdauer und Veränderbarkeit von Programmelementen festzulegen. Sie üben somit großen Einfluss auf die Eigenschaften von Variablen, Methoden und Klassen aus.

Im Folgenden werden wir jeden Java-Modifier kurz vorstellen und dabei jeweils auf die relevanten Auswirkungen auf Sichtbarkeit, Lebensdauer und Veränderbarkeit von Programmelementen eingehen.

Die unten aufgeführten Modifier sind in Java implementiert:

  • private
  • protected
  • public
  • standard (package scope)
  • static
  • final
  • transient
  • volatile

In unserem Beitrag Modifier in Java behandeln wir die Modifier von Java und gehen dabei ausführlich auf deren Eigenschaften ein.

Statische Variablen (Klassenvariablen), Konstanten und Methoden in Java

In Java können mit Hilfe von statischen Programmelementen Eigenschaften genutzt werden, die nicht an Instanzen (konkrete Objekte) einer Klasse gebunden sind. Statische Variablen existieren unabhängig von einem Objekt. Im Gegensatz zu Objektvariablen werden sie über die Klasse aufgerufen und nicht über ein konkretes Objekt.

Möchte man in Java eine statische Variable definieren, muss man diese mit Hilfe des Schlüsselworts static als statisch deklarieren, bspw. so: static private int anzObj;.

Der Zugriff auf diese statische Variable erfolgt über die Klasse, in der sie definiert ist, und zwar über den Klassennamen: Klassennamen.Variablennamen.

In Java wird jede statische Variable nur einmal angelegt und kann von allen Objekten dieser Klasse aufgerufen werden. Da sich alle Instanzen einer Klasse die Klassenvariablen teilen, wirken sich Änderungen, die durch eine Instanz an den statischen Variablen vorgenommen werden auch auf alle anderen Instanzen aus. In unserem Beitrag Statische Variablen, Konstanten und Methoden in Java gehen wir ausführlich auf die statischen Programmelemente von Java ein.

Daher können Klassenvariablen als globale Variablen angesehen werden, die vom Zeitpunkt ab dem ihre Klassen geladen wurden bis zum Programmende existieren. Da jede statische Variable über den Namen ihrer Klasse aufgerufen wird, können keine Namenskollisionen auftreten.

Abstrakte Klassen und Methoden in Java

Wird in Java eine Klasse mit dem Schlüsselwort abstract deklariert, gilt sie als abstrakt. Abstrakte Klassen können nicht instanziert werden. In abstrakten Klassen können abstrakte Methoden deklariert werden. Es sind aber auch normale, konkrete Methoden erlaubt.

Java-Entwickler setzen abstrakte Klassen als Superklassen ein, die abstrakte Methoden enthalten, welche erst später von abgeleiteten Klassen implementiert werden.

Solange die abstrakten Methoden nicht in den Subklassen implementiert wurden, können weder die Superklasse noch die Subklassen instanziert werden. Existieren auch in der Subklasse noch abstrakte Methoden, dann muss auch die Subklasse als abstrakte Klasse mit dem abstract-Schlüsselwort deklariert werden.

Erst wenn alle abstrakten Methoden der Superklasse implementiert worden sind, kann die Subklasse konkret werden (instanziert werden). Diese Konkretisierung kann auch schrittweise über mehrere Vererbungsstufen erfolgen.

In unserem Beitrag Abstrakte Klassen und Methoden in Java betrachten wir Klassen, die mindestens eine nicht implementierte (abstrakte) Methode besitzen. Wenn eine Klasse nicht implementierte Methoden besitzt, kann sie nicht instanziert werden und wird als abstrakte Klasse bezeichnet, da sie keine konkrete Form annehmen kann.

Innere Klassen in Java – Nichtstatische lokale Klassen

Innere Klassen können ab Java JDK 1.1 definiert werden. Java-Entwickler sind vor allem aufgrund des neuen Ereignismodells in JDK 1.1 auf das Verwenden von inneren Klassen angewiesen.

Im Englischen wird eine innere Klasse meist als inner class bezeichnet, im Deutschen wird sie oft auch lokale Klasse oder anonyme Klasse genannt. In unserem Beitrag Innere Klassen in Java – Nichtstatische lokale Klassen werden wir die innere Klasse in Form einer nichtstatischen lokalen Klasse behandeln.

Innere Klassen werden in Java wie normale Klassen behandelt. Vom Java-Compiler wird zu jeder inneren Klasse eine .class-Datei erzeugt. Der Dateiname setzt sich aus dem Namen der äußeren Klasse gefolgt von einem Dollarzeichen und dem Namen der inneren Klasse zusammen. Bei anonymen inneren Klassen wird statt des Namens der inneren Klasse eine fortlaufende Nummer vom Java-Compiler vergeben.

Was ist eine innere Klasse in Java?

Innere Klassen können in Java innerhalb von jeder beliebigen Klasse definiert werden, die damit zur äußeren Klasse wird. Die Definition einer inneren Klasse kann innerhalb der äußeren Klasse oder in einer ihrer Methoden erfolgen.

Eine innere Klasse kann nur innerhalb der äußeren Klasse instanziert werden. Dies kann während der Initialisierung der äußeren Klasse oder in einer ihrer Methoden erfolgen.

Die innere Klasse ist nur lokal sichtbar, daher werden innere Klassen in Java auch als lokale Klassen bezeichnet. Die innere Klasse kann auf alle Membervariablen und Methoden der äußeren Klasse zugreifen. Die äußere Klasse kann auf alle Membervariablen und Methoden aller inneren Klassen zugreifen.

Anonyme innere Klassen in Java

Eine weitere Form von inneren Klassen in Java sind anonyme Klassen. Diese besitzen, wie der Name schon nahelegt, keinen eigenen Klassennamen.

Eine anonyme Klasse wird in Java in einem kombinierten Schritt definiert und instanziert. Damit dies aber möglich ist, muss entweder:

  • eine andere Klasse bereits vorhanden sein, von der sich die anonyme Klasse ableitet oder
  • ein Interface, das von der anonymen Klasse implementiert wird

Eine große Bedeutung haben anonyme Klassen bei der Programmierung von grafischen Benutzeroberflächen, wo sie für die Definition von Listenern verwendet werden.

In unserem Beitrag Innere Klassen in Java – Mit anonymen Klassen Funktionszeiger nachbilden stellen wir jeweils eine Java-Beispielanwendung für jede der beiden Verwendungsarten von anonymen Klassen vor.

Statische lokale innere Klassen in Java

Neben lokalen nichtstatischen inneren Klassen können in Java auch statische innere Klassen angelegt werden. Wie bei den anderen inneren Klassen, werden statische lokale Klassen auch innerhalb äußerer Klassen definiert.

Durch das Schlüsselwort static werden die lokalen Klassen als statisch deklariert, bspw. mit folgender Klassendefinition: static class StaticInnerClass { ... }.

Statische lokale Klassen werden vom Java-Compiler wie normale globale Klassen angelegt. Der Name einer statischen lokalen Klasse setzt sich aus dem Namen der äußeren Klasse gefolgt von einem Punkt und dem Namen der inneren Klasse zusammen, etwa so: OuterClass.StaticInnerClass.

Die vom Compiler erzeugte .class-Datei enthält anstelle des Punktes als Trennzeichen das Dollarsymbol, etwa so: OuterClass$StaticInnerClass. In unserem Beitrag Innere Klassen in Java – Statische lokale Klassen gehen wir ausführlich auf die Eigenschaften statischer lokaler Klassen ein.

Eine statische lokale Klasse kann nicht auf die Membervariablen ihrer äußeren Klasse zugreifen, da sie keinen Verweis auf die instanzierende Klasse besitzt. Somit kann nicht auf die Instanz der äußeren Klasse mit OuterClass.this zugegriffen werden, da gar keine Instanz der äußeren Klasse existiert. Daher spricht man auch von statischen lokalen Klassen.

Eine statische lokale Klasse kann auch von außen instanziert werden und ist somit auch von außen sichtbar.

Wrapper-Klassen in Java

Eine Wrapper-Klasse kapselt die jeweilige primitive Variable in einem sehr einfachem Objekt. Dabei stellt die Wrapper-Klasse einige Methoden für den Zugriff auf die primitive Variable und nützliche Funktionen zur Verfügung.

In unserem Beitrag Einführung in Wrapper-Klassen in Java werden wir Wrapper-Klassen behandeln und eine kleine Einführung in dieses spannende Thema geben. Wir stellen die Wrapper-Klassen am Beispiel der vordefinierten Klassen für das leere Objekt void und die 8 primitiven Datentypen in Java vor.

Enumerations – Die Aufzählungsklasse von Java

In unserem Beitrag über Enumerations behandeln wir die Aufzählungsklasse von Java. In Java 5 wurden Enumerations in den Kern der Programmiersprache eingebaut.

Gleichzeitig wurde das neue Schlüsselwort enum eingeführt. Mit dem neuen Schlüsselwort enum werden in Java eigene Aufzählungstypen definiert. Die Syntax ist, wie an folgendem Beispiel zu erkennen ist, sehr einfach und intuitiv:

Auf die definierten Werte des Aufzählungstyps wird über Typname.WertA zugegriffen. Diese können einer Variablen vom Typ der Enumeration zugewiesen werden, etwa folgendermaßen: Typname variableX = Typname.WertA;.

In unserem nächsten Beitrag behandeln wir Vererbung und Polymorphismus in Java. Das Konzept der Vererbung ist in Java auf Einfachvererbung begrenzt, das heißt eine neue Klasse kann maximal von einer anderen Klasse abgeleitet werden. Andere objektorientierte Programmiersprachen verfügen über die Möglichkeit der Mehrfachvererbung, bei der eine Klasse von mehreren Klassen abgeleitet werden kann. Da dies aber auch Probleme mit sich bringt, wurde in Java nur die Einfachvererbung implementiert.

Mit dem folgenden Link gelangt ihr zurück zum Java Programmieren Lernen Kurs.

Comments 1

  1. Pingback: Verzweigungen in Java: Die if-else-, switch- und assert-Anweisung

Hinterlasse eine Antwort

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