# Klasse (Objektorientierung)

Unter einer Klasse (auch Objekttyp genannt) versteht man in der objektorientierten Programmierung ein abstraktes Modell bzw. einen Bauplan für eine Reihe von ähnlichen Objekten.
Die Klasse dient als Bauplan für die Abbildung von realen Objekten in Softwareobjekte und beschreibt Attribute (Eigenschaften) und Methoden (Verhaltensweisen) der Objekte. Verallgemeinernd könnte man auch sagen, dass eine Klasse dem Datentyp eines Objekts entspricht.

## Polymorphie

Darunter versteht man, dass von einer Klasse, die eine abstrakte Beschreibung einer Sache ist, viele Objektinstanzen erzeugt werden können. Diese sind dann alles konkrete Ausgestalltungen. Embarcadero Delphi Beispiel: Klasse TAuto und die Objektinstanzen RoterGolf: TAuto und Leichenwagen: TAuto. Beide sind von der Klasse TAuto, werden sich aber in vielen Details unterscheiden: der Gold hat rote Farbe, eine bestimmte Tankgröße und der Leichenwagen ist schwarz, hat eine andere Tankgröße und einen anderen aktuellen Tankinhalt und Sprittverbrauch als der Golf.

## Kapselung

Klassen fassen Daten und die Routinen die auf diesen Daten arbeiten (Methoden genannt) zusammen. Dabei kann man definieren, welche der Datenfelder und Methoden nur in der Klasse selbst und welche auch von externen Benutzern der aus der Klasse erzeugten Objekte benutzt werden können. Meistens gibt es die Sichtbarkeitsebenen private (nur in der Klasse sichtbar) protected (zusätzlich in Kindklassen sichtbar, siehe Vererbung weiter unten) und public (für alle Nutzer der Objekte der Klasse benutzbar). Beispiel: das Feld mit dem aktuellen Tankinhalt ist nur intern verfügbar, von außen kann darauf nur mit Methoden zugegriffen werden die den Wert des Feldes zurückliefern oder mittels denen der Tankinhalt geändert werden kann (sog. Setter). Die Setter Methode prüft dabei zum Beispiel, dass man beim Tanken nicht mehr Sprit in den Tank füllen kann als der Tank überhaupt fasst. Manche Programmiersprachen bieten noch weitere Sichtbarkeitsebenen um beispielsweise andere Klassen im selben Modul auf die Felder zugreifen zu lassen oder in Delphi published. Felder die in Delphi als published Properties definiert sind können im sog. Objektinspektor des Formulardesigners vom Anwender direkt geändert werden.

## Vererbung

Klassen können miteinander in hierarchischen Beziehungen stehen und zu komplexen Strukturen werden. Die Gesetzmäßigkeiten, nach denen diese gebildet werden, beschreibt das grundlegende Konzept der Vererbung. Hier sind weiterhin die Begriffe Basisklasse und abgeleitete Klasse von Bedeutung, um die Verhältnisse der Klassen untereinander zu charakterisieren. Dabei beschreibt die Basisklasse allgemeine Eigenschaften, ist also eine Verallgemeinerung der abgeleiteten Klassen. Diese sind somit Spezialisierungen der Basisklasse.
Beispiel: Basisklasse Kraftfahrzeug ist Verallgemeinerung der abgeleiteten Klassen (Spezialisierungen) Auto, LKW, Motorrad und Traktor.
Dabei „erben“ die abgeleiteten Klassen alle Eigenschaften und Methoden der Basisklasse (d. h., ein Motorrad hat alle Eigenschaften eines Kraftfahrzeugs, und man kann alles mit ihm machen, das man mit einem Kraftfahrzeug machen kann). Zusätzlich führt die abgeleitete Klasse zusätzliche Eigenschaften und Methoden ein, die bei ihren Objekten möglich sind. Das Motorrad hat z. B. einen Gepäckträger, ein Auto nicht, dafür aber einen Kofferraum.

## Programmierstil

In vielen Programmiersprachen ist es üblich, dass der Name einer Klasse mit einem Großbuchstaben beginnt und in Camel-Case-Notation geschrieben wird (Namenskonventionen von Java, JavaScript, .NET, Objective-C, PHP, Perl, Python, Swift). Die Namen der Variablen dagegen werden bei manchen Programmiersprachen mit einem Kleinbuchstaben begonnen.

## Vergleich mit Verbund

Ähnlich der Klasse ist der Verbund ein Werkzeug zum Verwalten von zusammengehörigen Attributen. Er ist ein zusammengesetzter Datentyp aus verschiedenen anderen Datentypen. Die einzelnen Komponenten können als Attribute des neuen Verbundtyps betrachtet werden. Je nach Programmiersprache können sich Verbund und Klasse mehr oder weniger stark unterscheiden. Beispiele für Unterschiede sind:
* Eigene Methoden und welche Arten möglich sind
* Speicherverwaltung
* Verhalten bei Zuweisung (nur Referenz, flache Kopie, tiefe Kopie)
* Nutz- und Definierbarkeit von Standardoperatoren
* Vererbbarkeit
* Unterstützung von Sichtbarkeiten, die nicht public sind
* Unterstützung von Unions
* Als Attribut zulässige Arten von Typen (Klassen, zusammengesetzte Typen, einfache Typen)

## Beispiele
### C#

Als Beispiel soll eine Lampe dienen. Eine Lampe kann verschiedene Eigenschaften (Attribute) besitzen, zum Beispiel Farbe, Gewicht und ob sie leuchtet. Da man mit den Eigenschaften Farbe und Größe wenig operieren kann, wäre eine sinnvolle Verhaltensweise demnach eine Lichtschalter-Methode, die den jeweiligen Zustand von an und aus bestimmt.
Beispiel-Implementierung in C#:
Das Konzept der Vererbung lässt sich daran zeigen, dass es verschiedene Arten von Lampen gibt, z. B. Straßenlaternen, Taschenlampen oder Autoscheinwerfer. Diese speziellen Lampenarten sind dann Unterklassen der Klasse Lampe, d. h. sie besitzen zusätzliche Attribute (z. B. Taschenlampe.maximaleLeuchtdauer, Autoscheinwerfer.istKippbar) und Methoden (z. B. Taschenlampe.batterieLaden, Autoscheinwerfer.fernlichtEinschalten). Die Attribute und Methoden der Klasse Lampe werden übernommen und gelten auch für die Unterklassen. Für diese speziellen Klassen ist die Klasse Lampe eine Basisklasse.
In C#:
Eine Klasse kann als Datentyp verwendet werden (z. B. für Attribute oder Methoden-Parameter).
Beispiel: Ein Parlament besteht aus mehreren Abgeordneten, die Person sowie meistens Mitglieder einer Partei sind. Die Klasse Abgeordneter ist als Unterklasse der Klasse Person umgesetzt. Jedes Parlament hat einen Abgeordneten als Vorsitzenden. Die Klasse Parlament kann eine Methode setzeVorsitzenden(...) definieren mit diesem Abgeordneter als Parameter; sie setzt das Attribut vorsitzender auf den angegebenen „Wert“. Zusätzlich wird eine Methode gibAnzahlDerAbgeordneten(...) implementiert, die einen Parameter der Klasse Partei erhält und die Anzahl der Abgeordneten dieser Partei zurückgibt.
Mögliche C#-Implementierung:

### Ruby

Das folgende Beispiel ist in der Programmiersprache Ruby geschrieben:
Dieses Programm definiert eine Klasse Fahrzeug und eine davon abgeleitete Klasse Auto.
Die Basisklasse besitzt eine Methode namens bewegen, die den Text „Fahrzeug wird bewegt.“ auf dem Computerbildschirm ausgibt. Die von Fahrzeug abgeleitete Klasse Auto hat ebenfalls eine Methode bewegen und überschreibt die Methode von Fahrzeug. Die von ihr erzeugte Ausgabe lautet „Auto wird bewegt.“.
Anschließend folgt die Definition einer eigenständigen Funktion fahren, die ein Objekt der Basisklasse als Argument bekommt. Auf diesem Objekt wird die Methode bewegen aufgerufen.
Schließlich folgt das Hauptprogramm, das sowohl ein Objekt der Basisklasse (fahrzeug), als auch der abgeleiteten Klasse (auto) erzeugt, und auf beide zuerst bewegen aufruft und danach mit Hilfe von fahren ebenfalls noch einmal bewegen für beide Objekte ausführt.
Wird dieses Programm ausgeführt, so erscheint auf dem Bildschirm:
Es ist zu erkennen, dass, obwohl die Funktion fahren für ein Fahrzeug definiert ist, sie auch für ein Auto funktioniert und die überschriebene Methode aufgerufen wird, d. h., sie funktioniert für Objekte der Basisklasse sowie für Objekte aller abgeleiteter Klassen. Diese erben die Eigenschaften und „können“ somit auch alles, was die Basisklasse „kann“. Dieses im Allgemeinen erwünschte Verhalten nennt man Polymorphie.

## Erweiterung

Eine Erweiterung bzw. Abstraktion dieses Konzepts findet sich in dem Modell der abstrakten Klassen und der Metaklassen.
Möglich ist auch eine sogenannte anonyme Klasse. Dabei wird eine Klasse nur an genau der Stelle beschrieben, an der ein Objekt von ihr erzeugt wird. Sie ist nicht getrennt (zum Beispiel in einer eigenen Datei) als eigenständige Komponente im Quellcode beschrieben und kann daher auch von anderen Programmteilen nicht wiederverwendet oder gezielt angesprochen werden. Die Klasse erhält auch keinen eigenen Namen. In der Regel erbt sie jedoch von einer anderen, diese beschreibt dann die Haupteigenschaften und -methoden des Objekts für seine spätere Verwendung. Die abgeleitete, namenlose Klasse modifiziert das Verhalten meist nur geringfügig.
Ein Beispiel in Java:
Es wird mit new ein Objekt erzeugt, das in Hauptsache einem java.awt.event.ActionListener entspricht (zwar keine Basisklasse, aber ein Interface). Als spezielle Verhaltensweise genau diesen Objekts wird die Methode actionPerformed so überschrieben, dass sie Hilfetext auf dem Bildschirm ausgibt. Da ein spezialisiertes Verhalten definiert wurde, ist das Objekt von einer abgeleiteten Klasse, also nicht von ActionListener direkt – es wurde aber kein Klassenname angegeben. Im nachfolgenden Programm kann das Objekt nur noch als ActionListener verwendet werden (siehe Polymorphie).
Mitunter wird ähnlich einer anonymen Klasse auch eine innere Klasse definiert. Unterschied zu einer „normalen“ Klasse ist zunächst der Sichtbarkeitsbereich, eine innere Klasse ist innerhalb einer anderen („äußeren Klasse“) definiert. Ist sie privat, so können nur Objekte der äußeren Klasse Objekte der inneren erzeugen und verwenden. Ist die innere Klasse nicht-statisch, so ist eine Objekterzeugung sogar abhängig von einem Objekt der äußeren Klasse und nur über ein solches Objekt möglich.

## Reflexion

Manche Programmiersprachen erlauben es, dass ein Programm die Struktur seiner Klassen kennt und auch das Verändern von Klassen zur Laufzeit, wie beispielsweise das Ändern der Struktur durch Hinzufügen oder Entfernen von Eigenschaften oder Methoden. Diese sogenannte „Reflexion“ sollte nur im Notfall verwendet werden, da das Programm dadurch schwer verständlich und Refactoring erschwert wird.