Zum Inhalt

Object Oriented Programming (OOP)

Ein moderner Ansatz in der Softwareentwicklung ist es, Objekte der realen Welt abstrahiert in die virtuelle Welt zu übertragen. Alle Objekte der realen Welt haben Eigenschaften und mögliche Verhaltensweisen.
In der virtuellen Welt werden Klassen als „Baupläne“ verwendet, auf deren Basis beliebig viele gleichartige Objekte erstellt (instanziiert) werden können.

flowchart TB
    Klasse --> Objekt1
    Klasse --> Objekt2
    Klasse --> Objekt3
    Klasse --> ObjektN

Eine Klasse enthält:

  • Attribute: Beschreiben die Eigenschaften eines Objekts. In den Attributen ist quasi das „Wissen“ gespeichert.
  • Methoden: Beschreiben die Funktionalitäten/Operationen eines Objekts. Methoden können z.B. Attribute der Klasse ausgeben oder bearbeiten.

Die Struktur eines Programms wird mit Hilfe von UML-Klassendiagrammen grafisch dargestellt. Das Klassendiagramm beschreibt, unter anderem, Klassen und deren Beziehungen untereinander. Eine Klasse wird allgemein folgendermaßen dargestellt:

classDiagram
class Klassenname{
    Sichtbarkeit Attributname:Datentyp
    Sichtbarkeit Methodenname(Parameter:Datentyp, ...):Rückgabetyp
}

Konstruktor

Wenn Sie ein Objekt einer Klasse instanziieren wollen, rufen Sie folgenden Befehl aus:

Klasse objekt1 = new Klasse()
Diese Methode Klasse(), die den gleichen Bezeichner trägt, wie die Klasse, nennt man Konstruktor.
Jedes Mal, wenn wir mit Hilfe des new-Operators ein neues Objekt erzeugen, rufen wir daher automatisch den entsprechenden Konstruktor der Klasse auf. Dieser führt dann alle Anweisungen aus, die er enthält. Wird in einer Klasse kein bestimmter Konstruktor erstellt, erhält diese automatisch einen parameterlosen Konstruktor, der keinerlei Anweisungen enthält. Im Gegensatz zu einer gewöhnlichen Methode wird beim Konstruktor kein Rückgabetyp angegeben, auch nicht void.

Regeln für Konstruktoren

  • Sie haben den gleichen Namen wie die Klasse
  • Sie haben keinen Rückgabetyp (auch nicht void)
  • Ist der Konstruktor nicht definiert, so hat die Klasse dennoch einen Konstruktor, den man Standardkonstruktor (das entspricht einem Konstruktor ohne Parameter) nennt

Standardkonstruktor

Der Standardkonstruktor steht jeder Klasse automatisch zur Verfügung, auch wenn er in der Klasse nicht explizit angegeben wurde.

Definition in der Klasse

Möchte man den Standardkonstruktor manuell der Klasse hinzufügen, wird er in der Klasse =Konto= so angegeben:

public Klasse()
{

}

Erzeugung des Objekts

Ein Objekt kann durch Aufruf des Konstruktors instanziiert werden:

Klasse objekt1 = new Klasse();

Überschriebener Konstruktor

Möchten man, dass der Standardkonstruktor beim Aufruf noch eine Funktionalität ausführt, wie beispielsweise bestimmte Attribute initialisieren, erweitern Sie seinen Rumpf. Hier wird ein Attribut beim Erzeugen des Objekts (also beim Aufruf des Konstruktors) auf 10 gesetzt:

public Klasse()
{
  this.attribut = 10;
}

Das Wort „this“ stellt in diesem Zusammenhang einen Verweis auf das aktuelle Objekt dar. Dies ist das gerade aktive Objekt.

Erzeugung des Objekts

Ein Objekt kann durch Aufruf des Konstruktors instanziiert werden:

Klasse objekt1 = new Klasse();

Überladener Konstruktor mit Übergabeparametern

Konstruktoren können auch Übergabeparameter erhalten. Dies kann man idealerweise dafür nutzen, um bestimmte Attribute direkt beim Erzeugen des Objektes zu initialisieren. Der Einsatz von Übergabeparametern gestattet es, die Werte für die Attribute durch den Benutzer bestimmen zu lassen.
Eine Klasse kann auch mehrere Konstruktoren gleichzeitig besitzen, wenn sich jeder Konstruktor über die Parameterliste (sowohl Anzahl an Attributen, als auch Datentyp) unterscheiden lässt. Man nennt die Konstruktoren dann überladen.

Definition in der Klasse

public Klasse(int parameter)
{
    this.attribut = parameter;
}

Erzeugung des Objekts

Klasse objekt1 = new Klasse(50);

Warning

Sobald Sie einen Konstruktor in Ihrer Klasse angeben, der Übergabeparameter empfängt, und kein Standardkonstruktor in Ihrer Klasse vorkommt, existiert der Standardkonstruktor auch nicht mehr in Ihrer Klasse und kann auch nicht mehr aufgerufen werden.

Datenkapselung

Bei der Datenkapselung geht man von der Idee aus, dass alle Attribute einer Klasse vor Zugriffen von außen geschützt werden. Ob bzw. wie auf Attribute zugegriffen werden kann wir über die Sichtbarkeit jener geregelt. Der Zugriff auf die Attribute wird nur über den Aufruf von öffentlichen Methoden, die zur Verfügung gestellt werden, gestattet.

Zugriffsmodifikatoren

Es werden sogenannte Zugriffsmodifikatoren verwendet. Man unterscheidet zwischen folgenden Zugriffsmodifikatoren:

  • Minus (-) steht für private: Nur innerhalb der Klasse kann auf solche Variablen und Methoden zugegriffen werden.
  • Plus (+) steht für public: Jede Klasse kann auf die Variable oder Methode zugreifen.
  • Raute (#) steht für protected: Auf die Variable oder Methode kann nur innerhalb der Klasse und in vererbten Klassen zugegriffen werden.

Zugriffsmethoden

Diese Methoden dienen als Schnittstelle zwischen den Attributen der Objekte und der Außenwelt.

Get-Methoden

Get-Methoden sind Methoden ohne Übergabeparameter, aber mit Rückgabeparameter. Im Rückgabeparameter wird das jeweilige Attribut, zu der die Get-Methode zugehörig ist, zurückgegeben.

Syntax
public int getAttribut()
{
    return attribut;
}

Set-Methoden

Set-Methoden sind Methoden mit Übergabeparameter und ohne Rückgabeparameter. Mit einer Set-Methode wird der Wert eines Attributs festgelegt. Man übernimmt dabei den Wert des Übergabeparameters.

Syntax
public void setAttribut(int parameter)
{
    attribut = parameter;
}

Klassenvariablen

Es gibt zwei Arten von Variablen im Zusammenhang mit Klassen - Klassenvariablen und Objektvariablen, die danach klassifiziert werden, ob die Klasse oder das Objekt die jeweiligen Variablen besitzt. Unter dem Begriff Variablen verstehen wir die Attribute einer Klasse.

Objektvariablen gehören den einzelnen Objekten (Instanzen) der Klasse individuell. In diesem Fall hat jedes Objekt seine eigene Kopie des Attributs oder der Methode, d.h. sie werden nicht gemeinsam benutzt und sind auf keine Weise mit der Variable des gleichen Namens in einer anderen Instanz derselben Klasse verknüpft. Jedes Objekt hat seine eigene Ausprägung eines Attributs.

Klassenvariablen werden gemeinsam benutzt, in dem Sinne, dass auf sie von allen Objekten (Instanzen) der Klasse zugegriffen wird. Es gibt nur eine Kopie einer Klassenvariable, und wenn irgendein Objekt eine Änderung an einer Klassenvariable vornimmt, dann spiegelt sich diese Änderung sofort auch in allen anderen Instanzen der Klasse wieder.
Ein Klassenattribut ist für alle Objekte der Klasse gleich. Eine Klassenmethode ist eine Methode der Klasse und betrifft die gesamte Klasse, nicht die Objekte.

Syntax

Klassenvariable/-methide in der Klasse

Klassenvariablen werden mit der Erweiterung =static= gekennzeichnet.

Attribut
private static double attribut = 19;
Methode
public static double getAttribut()
{
      ...
}

Aufruf/Zugriff

Objektvariable
objekt1.Attribut = "Hello World!";
objekt1.getAttribut();
Klassenvariable
Klasse.Attribut = "Hello World!"
Klasse.getAttribut();

Vererbung

Vererbung ist ein elementares Konzept der objektorientierten Programmierung. Besitzt man mehrere Klassen, die zwar Gemeinsamkeiten, aber auch Unterschiede haben, könnte es Sinn machen, dass beide Klasse von einer verallgemeinerten Form dieser Klassen erben.
Man erzeugt eine neue Klasse und definiert, dass es sich dabei um eine Generalisierung der anderen Klassen handelt. Man kann es sich so vorstellen:

„Jedes Objekt der Kindklasse besitzt alle Eigenschaften und Methoden der Elternklasse, aber evtl. besitzt es noch weitere Attribute und/oder Methoden. Jedes Objekt der Kindklasse erbt die Eigenschaften von der Elternklasse. Die Kindklasse ist also eine Spezialisierung der Elternklasse.“

Die bestehende Klasse (Elternklasse) bezeichnet man als Basisklasse, die Klasse, die erbt (Kindklasse), die Abgeleitete Klasse.

public class Kindklasse : Elternklasse
{
    
}

Klassen in C#

In C# kann eine Klasse nur eine Basisklasse besitzen! Aber eine Basisklasse kann mehrere Abgeleitete Klassen haben.

Abstrakte Klasse

Möchte man nicht, dass von der Basisklasse Objekte erzeugt werden, kann die Klasse als abstrakt deklariert werden.

abstract class Elternklasse
{ ... }

Überschreiben von Methoden

Zwar erbt eine abgeleitete Klasse die Methoden ihrer Basisklasse. Möchte man diese Methoden in der abgeleiteten Klasse aber verändern, weil die Logik oder das Verhalten nicht mehr korrekt ist, so lässt sich diese Methode in der abgeleiteten Klasse überschreiben.

Beispiel

Basisklasse
class Elternklasse
{
    public virtual double methode()
    ... 
}
Abgeleitete Klasse
class Kindklasse : Elternklasse
{
    public override double methode()
    ... 
}

Regeln

  • Beide Methoden müssen den gleichen Namen (Bezeichner) haben
  • Beide Methoden müssen den gleichen Datentyp (Rückgabewert) haben
  • Beide Methoden müssen die gleiche Parameterliste (Anzahl und Datentyp) haben

Assoziationen

Das Klassendiagramm stellt die Struktur eines Programmes grafisch dar. Neben dem Aufbau einzelner Klassen enthält das Klassendiagramm unter anderem auch die Verbindungen (=Assoziationen) dieser Klassen untereinander.
Es werden drei Arten von Assoziationen unterschieden:

Einfache Assoziation

Eine Art Brücke zwischen zwei Klassen. Über Instanziierungen stehen zwei (oder mehrere) Klassen miteinander in Verbindung. Solche Beziehungen werden durch eine Linie veranschaulicht. Pfeilspitzen am Ende der Linie geben die Zugriffsrichtung und die an der Linie stehenden Zahlen geben die Multiplizitäten an. Außerdem werden Rollennamen angegeben, die man als Hinweis auf die Bezeichnung des Attributs in der führenden Klasse verstehen kann.

Die Multiplizität Gibt die Anzahl der Instanzen an, mit denen eine Assoziation besteht. Folgende Angaben sind möglich:

Multiplizität Beschreibung Beispiele
<zahl> Anzahl der Instanzen entspricht zahl 1
<untereSchranke>..<obereSchranke> Die untere Schranke muss kleiner sein als die obere, wobei * bei der oberen Schranke für den Wert /unbeschränkt/ steht 0..1..1..50..1

Aggregation

Eine Aggregation stellt eine „ist Teil von“-Beziehung dar. Im Grunde lässt sich diese nicht von der einfachen Assoziation unterscheiden. Die Unterscheidung zwischen Aggregation und Assoziation führt oft zu heftigen (und unnötigen) Diskussionen. Die Aggregation wird mit einer nicht ausgefüllten Raute dargestellt. Die Raute befindet sich auf der Seite des „Ganzen“. Das „Teil-Objekt“ kann ohne das „Ganz-Objekt“ existieren.

Komposition

Die Komposition ist eine stärkere „ist Teil von“-Beziehung und wird mit einer ausgefüllten Raute dargestellt. Die Raute befindet sich auf der Seite des „ganzen“. Das „Teil-Objekt“ kann ohne das „Ganze-Objekt“ nicht existieren. Wird das „Ganze-Objekt“ gelöscht, werden auch die „Teil-Objekte“ gelöscht.