Objektorientierte Programmierung

Objektorientierte Programmierung, auch OOP genannt, ist ein High-Level-Programmiermodell, das sich von der prozeduralen und funktionalen Programmierung unterscheidet und von den meisten Entwicklern erlernt und angewendet wird. Dieses Modell der Softwareprogrammierung konzentriert sich auf Daten und Objekte, statt auf Funktionen und Logik.

Um mit OOP zu arbeiten, müssen Entwickler eine Gruppe von zusammenhängenden Variablen und deren Funktionen zu einer Einheit zusammenfassen. Diese Einheit ist das Objekt. Diese Praxis wird Datenmodellierung genannt. Die Datenmodellierung in OOP wird verwendet, um reale Objekte mit ihren Eigenschaften und Verhaltensweisen zu repräsentieren. Die Manipulation erfolgt an den Objekten selbst - an ihren Zuständen und Verhaltensweisen und nicht an den Daten und Funktionen.
Die erste objektorientierte Programmiersprache hieß Simula. Sie wurde in den 1960er Jahren am Norwegian Computing Center in Oslo entwickelt und gilt allgemein als die erste Sprache mit allgemeinen Programmierspracheneigenschaften. Trotzdem gilt eine andere Sprache, nämlich Smalltalk, die in den 1980er Jahren entwickelt wurde, als die einzig wahre objektorientierte Sprache. Sie gab den Weg vor, dem andere objektorientierte Sprachen folgen müssen.
Viele moderne Programmiersprachen, wie Python und JavaScript, unterstützen sowohl die objektorientierte als auch die prozedurale Programmierung. Sprachen wie Java sind rein objektorientiert, während Sprachen wie C++ sowohl als objektorientierte Sprachen als auch als eine Programmiersprache mit objektorientierten Funktionen angesehen werden. Dies liegt daran, dass sie weniger objektorientiert sind als andere Sprachen, wie z.B. Ruby.

Unterschied zwischen objektorientierter und prozeduraler Programmierung

Die prozedurale Programmierung ist die häufigste Art der Programmierung, die in Sprachen wie JavaScript und Python verwendet wird. Sie ist die am häufigsten gelehrte und die erste Art der Programmierung, mit der die meisten Entwickler in Berührung kommen.
Der Code für prozedurale Programmierung folgt einem Top-Down-Ansatz von logischen Schritten und Algorithmen. Er trennt Daten und Prozeduren. Diese Prozeduren werden Funktionen, Routinen und Subroutinen genannt.
Die objektorientierte Programmierung hingegen ist ein Programmierparadigma, bei dem Berechnungen mit Objekten und Daten gemeinsam durchgeführt werden. OOP verwendet Klassen, um neue Objekte und Instanzen zu erstellen.
Ein Unterschied zwischen OOP und prozeduraler Programmierung ist, dass OOP Prinzipien wie Abstraktion, Vererbung, Kapselung und Polymorphismus verwendet, was es sicherer macht gegenüber der prozeduralen Programmierung.

Klasse

Eine Klasse ist ein Bauplan eines Objekts. Sie sind der Baustein der OOP. Sie repräsentieren alle Kategorien eines Objekts und definieren die Methoden, die mit einem Objekt verbunden sind. Eine Instanz ist ein konkretes Objekt, das erzeugt wird. Eine Klasse beschreibt ein Objekt.
Wenn ein Objekt erstellt wird, beschreiben wir seine Aktion und Eigenschaften mit einer Klasse. Da es sich bei Objekten um Simulationen des realen Lebens handelt, kann es viele Instanzen derselben Klasse geben.
Nehmen wir an, wir haben einen Hund in unserem Programm. Es gibt Tausende von Hunden auf der Welt – verschiedene Rassen, Formen, Farben, unterschiedliche Ausprägungen in Gewicht und Höhe. Wir müssten eine Klasse namens „Hund“ erstellen. Diese Klasse wäre die Blaupause eines Hundes, mit den physischen Eigenschaften eines Hundes und den damit verbundenen Methoden. Unser Hund wird eine Instanz der Klasse „Hund“ sein.
Um verschiedene Instanzen eines Hundes zu erstellen, müssen wir diese nicht von Grund auf neu erstellen, sondern wir verwenden die Blaupause von „Hund“, um so viele Hundeobjekte zu erstellen, wie wir wollen.

Erstellen einer Klasse

Klassen werden normalerweise mit dem Schlüsselwort „class“, gefolgt von einem Initialisierer oder Konstruktor, erstellt. In Java wird der Konstruktor mit dem Zugriffsmodifikator definiert und nimmt den Namen der Klasse an, jedoch ohne Rückgabetyp.
In Python ist das Schlüsselwort „__init__“ der Klassenkonstruktor und er wird aufgerufen, wenn wir eine Instanz einer Klasse erzeugen.

Hier ist ein Beispiel für eine Hundeklasse „Hund“ in Java und Python.

Java

public class Hund { 
  private String name; 
  private String breed; 
 
  public Hund (String name, String breed)  
  { 
    This.name = Sammy;  //properties 
    This.breed = Labrador;     //properties 
  }  
 
  //The method 
  public void speak() 
  { 
    System.out.println("Mein Hund heißt " + this.name + "und er ist ein " + this.breed) 
  }
}

Python

class Hund(): #Erstellen einer Klasse
  #KLASSE OBJEKT ATTRIBUT
  species = "Säugetier"
  def __init__(self, breed, name):   #dies ist eine Methode zum Initialisieren einer Klasse. self ist wichtig
    self.breed = breed   #Eigenschaften
    self.name = name     #Eigenschaften

myDog = Dog("labrador","Sammy") 
print(myDog.breed) #labrador 
print(myDog.name) #sammy 

Bedeutung von Klassen

  • Sie bieten einen Bauplan oder eine Vorlage für die Erstellung von Objekten
  • Sie unterstützen die Vererbung
  • Wiederverwendbarkeit von Code

Instanz, Methoden und Eigenschaften

Eine Instanz ist ein individuelles oder spezifisches Objekt, das erzeugt wird. Ein Objekt, „MeinHund“, das zu einer Klasse Hund gehört, ist eine Instanz.
Methoden sind in der OOP Aktionen, die von einem Objekt ausgeführt werden. Sie sind an bestimmte Klassen gebunden (Bindung ist die Assoziation zwischen einer Methode und einer Klasse) und können vordefiniert oder benutzerdefiniert sein. Eingebaute Methoden sind Methoden, die von der Sprache vordefiniert sind, wie z.B. „len“ in Python, das die Länge berechnet. Benutzerdefinierte Methoden sind vom Entwickler geschriebene Operationen, die mit einer Klasse ausgeführt werden.

Methoden sind für OOP das, was Funktionen für die Prozedurale Sprache sind. Sie sind wiederverwendbar und können vererbt werden. Eigenschaften sind wie Variablen. Sie sind die Beschreibung eines Objekts. Zum Beispiel hat ein Hund Länge, Farbe, Gewicht und Höhe. Diese Attribute sind die Eigenschaften des Hundes.

Prinzipien der OOP

OOP hat vier wichtige Grundkonzepte oder Prinzipien. Das Verständnis dieser Prinzipien und ihrer Funktionsweise ist der erste Schritt zum Verständnis von OOP.

Vererbung

Vererbung ist ein Konzept, das die Erstellung neuer Klassen aus einer bestehenden Klasse ermöglicht. Die vererbte Klasse wird zu einer Unterklasse oder Kinderklasse der Ober- oder Elternklasse. Es gibt verschiedene Arten der Vererbung:

  • Einfache Vererbung
  • Mehrfache Vererbung
  • Hierarchische Vererbung
  • Hybride Vererbung
  • Mehrstufige Vererbung

Wenn eine Klasse vererbt wird, verfügt sie über alle Felder und Methoden der übergeordneten Methode und zusätzlich über deren spezifische Methoden und Funktionalitäten. Vererbung macht eine Klasse DRY (Don't Repeat Yourself).
Ein praktisches Beispiel für die Vererbung ist die Beziehung zwischen einem Elternteil und seinem Kind. Wenn ein Kind geboren wird, erbt es einige Gene von seinem Elternteil, aber es ist auch eine eigenständige Person mit eigenen, einzigartigen Merkmalen.

Verkapselung

Auch Data Hiding genannt, ist ein wichtiger Aspekt von OOP. Dieses Konzept legt Beschränkungen innerhalb einer Klasse fest, um die Daten und den Code innerhalb einer einzigen Einheit zusammenzuhalten und zu schützen. Die Kapselung verhindert den einfachen Zugriff auf Eigenschaften und Methoden, was eine versehentliche oder nicht genehmigte Änderung von Daten verhindert.
Ein praktisches Beispiel für Kapselung ist ein Unternehmen mit verschiedenen Abteilungen. Ein Manager in der Vertriebsabteilung hat keinen Zugriff auf die Dokumente in der Buchhaltungsabteilung. Um an die dortigen Dateien zu gelangen, müsste der Vertriebsleiter den Zugriff bei der Buchhaltung beantragen.
Eine Klasse ist ein Beispiel für eine Kapselung. Alle ihre Methoden, Eigenschaften und Variablen sind innerhalb der Klasse selbst verborgen. Zugriffsmodifikatoren - wie öffentlich, privat oder geschützt - sind erforderlich, um die Art des Zugriffs auf einen Code zu bestimmen.

Abstraktion

Abstraktion ist ein Konzept, das uns erlaubt, interne Details vor äußeren Einflüssen zu verbergen. Es ist die Darstellung komplexer Dinge auf einfache Art und Weise.
Bei der Abstraktion werden die internen Mechanismen eines Programms und jeder andere Implementierungscode verborgen. Nur relevante Details werden offengelegt. Sie wird verwendet, um eine Grenze zwischen der Anwendung und dem Benutzer zu schaffen.
Ein praktisches Beispiel für Abstraktion ist die Anmeldung bei einer Webseite. Wenn Sie Ihren Namen, Ihre E-Mail-Adresse und Ihr Kennwort in ein Formular eingeben, sind Sie nicht in die Feinheiten der Server- und https-Protokolle eingeweiht und wissen nicht, wie Ihre Daten authentifiziert werden. Alles, was Sie bekommen, ist eine Erfolgs- oder Fehlermeldung bei der Anmeldung.

Polymorphismus

Polymorphismus ist die Fähigkeit verschiedener Objekte, als Reaktion auf einen Code verschiedene Formen anzunehmen. Polymorphismus modelliert das reale soziale Umfeld, in dem verschiedene Personen auf unterschiedliche Weise auf eine Aktion reagieren können. Es erlaubt uns, eine Instanz zu definieren und mehrere Implementierungen davon zu bekommen.

Zugriffsmodifikatoren

Zugriffsmodifikatoren (access modifiers) sind Schlüsselwörter in OOP-Sprachen, die die Zugänglichkeit von Klassen, Methoden und anderen Mitgliedern festlegen. Zugriffsmodifikatoren werden verwendet, um Kapselungen zu implementieren. Die drei wichtigsten Modifikatoren sind öffentlich, privat und geschützt. C++ und Python haben diese drei, Java hat vier und C# erweitert die Anzahl auf sechs. Jede Sprache hat ihre eigene Art, ihre Zugriffsmodifikatoren zu definieren.

ÖFFENTLICHER ZUGRIFF (PUBLIC ACCESS)

Dies ist der primäre und Standardmodifikator. Wenn eine Klasse als öffentlich definiert ist, ist sie für jede andere Klasse, die als öffentlich definiert ist, und auch für Klassen mit anderen Zugriffsmodifikatoren zugänglich. Sie hat keine Einschränkung des Geltungsbereichs. Wenn es notwendig ist, eine öffentliche Klasse zu debuggen, könnte der Fehler von überall und aus jedem Paket im Code kommen.
Ein Entwickler, der nicht möchte, dass sein Code von irgendjemandem verändert wird, aber dennoch möchte, dass andere Prozesse die Daten lesen können, kann seinen Code auf geschützt oder privat stellen und mit einer öffentlichen Funktion versehen.
In Java wird eine öffentliche Klasse durch das Schlüsselwort „public“ beim Konstruktor gesetzt. In Python sind alle Klassen standardmäßig öffentlich, sofern nicht anders angegeben.

GESCHÜTZTER ZUGRIFF (PROTECTED ACCESS)

Auf geschützte Methoden kann nur von der Klasse, in der sie definiert sind, und von allen anderen Unterklassen oder geerbten Klassen zugegriffen werden. In Java werden geschützte Klassen mit dem Schlüsselwort „protected“ im Konstruktor definiert.

class Hund  { 
  // protected method 
  protected void display() { 
    System.out.println("Dies ist ein Hund"); 
  } 
}

In Python werden geschützte Klassen definiert, indem ein einzelner Unterstrich (_) als Präfix an die Variablen angehängt wird.

class Hund(): 
  def__init__(self, name, breed) 
    self._name = name 
    self._breed = breed

PRIVATER ZUGANG (PRIVATE ACCESS)

Eine private Methode ist eine Methode, die nur für die Klasse verfügbar ist, in der sie definiert ist. Private Methoden sind in der Regel am einfachsten zu debuggen, da Fehler nur innerhalb der Methode enthalten sind. In Python werden zwei Unterstriche (__) als Präfixe an die Variablen angehängt, um eine Methode auf privat zu setzen.
In Java können Schnittstellen und Klassen nicht als privat deklariert werden, nur verschachtelte Klassen können das.

Fazit

Trotz seiner einzigartigen Vorteile - Wiederverwendbarkeit, Instandhaltung, schnellere Entwicklung, hohe Qualität der Software und verbesserte Produktivität der Softwareentwicklung - wird OOP von einigen Entwicklern kritisiert. Sie greifen die steile Lernkurve, den aufgeblähten Code (aufgrund des Missbrauchs von Vererbung) und den gemeinsam genutzten veränderbaren Zustand an.

Autor

Ivan Georgiev | Mid Softwareentwickler

Ivan ist ein äußerst intelligenter und sachkundiger Fachmann mit einem Hunger nach Verbesserung und kontinuierlichem Lernen. Er ist vielseitig in einer Reihe von Programmiersprachen und lernt innerhalb weniger Stunden neue Technologien kennen. Er ist eine Person, die Herausforderungen durch Untersuchung und klar strukturierte Ausführung meistert und seine Erfahrung und innovative Ideen einbringt, um Probleme schnell und effizient zu lösen. Ivan ist auch ein Zertifizierter Shopware Entwickler.