Python OOP – Objektorientierte Programmierung

6 Kernkonzepte
Die wichtigsten OOP-Konzepte in Python: class · __init__ / self · Vererbung · Polymorphie · Dunder-Methoden · @property Objektorientierte Programmierung in Python ermöglicht die Strukturierung von Code durch Klassen, Vererbung und Polymorphie. Diese Konzepte sind die Grundlage für saubere, wiederverwendbare und erweiterbare Software.

Klassen & Objekte – Blaupause und Instanz

class · __init__ · self · object
class Person: def __init__(self, name, age): self.name = name self.age = age p1 = Person("Anna", 30)

Klassen sind Blaupausen für Objekte. Der Konstruktor __init__() initialisiert die Attribute, self verweist auf die aktuelle Instanz.

Wichtige Konzepte

Konzept Beschreibung
class Definiert eine neue Klasse (Blaupause)
__init__ Konstruktor – wird beim Erstellen aufgerufen
self Verweis auf die aktuelle Instanz (ähnlich this)
object Instanz einer Klasse
Attribute Daten, die zur Klasse gehören (self.name)
Methoden Funktionen, die zur Klasse gehören
Beispiele
class Auto:
def __init__(self, marke, modell):
self.marke = marke
self.modell = modell
self.km = 0
def fahren(self, strecke):
self.km += strecke
print(f"{self.marke} {self.modell} fährt {strecke} km")
mein_auto = Auto("VW", "Golf")
mein_auto.fahren(100)
print(f"Kilometerstand: {mein_auto.km}")
VW Golf fährt 100 km
Kilometerstand: 100
Tipp: Der erste Parameter jeder Methode muss self sein (auch wenn Sie ihn nicht verwenden). Er wird automatisch übergeben und referenziert die aktuelle Instanz.

__init__ & self – Konstruktor und Instanzreferenz

__init__ · self · Attribute
def __init__(self, name, age): self.name = name self.age = age

__init__ ist der Konstruktor, der automatisch aufgerufen wird, wenn ein Objekt erstellt wird. self ist die Referenz auf die aktuelle Instanz.

Wichtige Konzepte

Konzept Beschreibung
__init__ Konstruktor – wird bei der Instanzerstellung aufgerufen
self Referenz auf die Instanz (für Attribute und Methoden)
Instanzattribute Attribute, die pro Instanz definiert werden (self.attr)
Klassenattribute Attribute, die für alle Instanzen gleich sind (direkt in der Klasse)
Beispiele
class Student:
# Klassenattribut (für alle Instanzen gleich)
schule = "Max-Schule"
def __init__(self, name, klasse):
# Instanzattribute (pro Instanz unterschiedlich)
self.name = name
self.klasse = klasse
def vorstellen(self):
print(f"Ich bin {self.name}, Klasse {self.klasse}, Schule: {Student.schule}")
s1 = Student("Anna", "10a")
s2 = Student("Ben", "10b")
s1.vorstellen()
s2.vorstellen()
Ich bin Anna, Klasse 10a, Schule: Max-Schule
Ich bin Ben, Klasse 10b, Schule: Max-Schule
Tipp: Klassenattribute werden von allen Instanzen geteilt. Änderungen an Klassenattributen wirken sich auf alle Instanzen aus – nützlich für globale Einstellungen.

Vererbung – Klassen hierarchisch erweitern

class Child(Parent) · super()
class Child(Parent): def __init__(self, arg): super().__init__(arg)

Vererbung ermöglicht es, eine neue Klasse auf Basis einer bestehenden zu definieren. Die Kindklasse erbt alle Attribute und Methoden der Elternklasse.

Wichtige Konzepte

Konzept Beschreibung
class Child(Parent) Vererbung von Parent
super() Ruft Methode der Elternklasse auf
Methoden überschreiben Kindklasse definiert eigene Methode
isinstance() Prüft, ob Objekt zur Klasse gehört
issubclass() Prüft, ob Klasse von anderer erbt
Beispiele
class Tier:
def __init__(self, name):
self.name = name
def laut(self):
print("Ein Tier macht Geräusche")
class Hund(Tier):
def laut(self): # Überschreiben
print(f"{self.name} bellt: Wau wau!")
class Katze(Tier):
def laut(self):
print(f"{self.name} miaut: Miau!")
tiere = [Hund("Bello"), Katze("Mieze")]
for tier in tiere:
tier.laut()
print(isinstance(tiere[0], Hund)) # True
print(issubclass(Hund, Tier)) # True
Bello bellt: Wau wau!
Mieze miaut: Miau!
True
True
Tipp: Mit super() rufen Sie die Methode der Elternklasse auf – das ist besonders nützlich im Konstruktor, wenn Sie die Initialisierung der Elternklasse nicht selbst neu schreiben möchten.

Polymorphie – Viele Formen, eine Schnittstelle

Methoden-Überschreibung · Duck-Typing
# Jede Klasse implementiert die gleiche Methode for obj in [Hund(), Katze(), Vogel()]: obj.laut()

Polymorphie bedeutet, dass verschiedene Klassen die gleiche Methode implementieren, aber unterschiedliches Verhalten zeigen. Python unterstützt dies durch Methoden-Überschreibung und Duck-Typing.

Wichtige Konzepte

Konzept Beschreibung
Überschreibung Kindklasse definiert eigene Methodenimplementierung
Duck-Typing "Wenn es wie eine Ente läuft und quakt..." – Typ wird nicht geprüft, nur Verhalten
Abstrakte Klassen ABC-Modul für obligatorische Methoden (nicht explizit gezeigt)
Liskov-Substitution Instanz der Kindklasse kann überall verwendet werden, wo die Elternklasse erwartet wird
Beispiele
class Vogel:
def laut(self):
print("Piep piep!")
class Ente:
def laut(self):
print("Quak quak!")
# Duck-Typing: Es wird nur geprüft, ob die Methode existiert
def tier_laut_machen(tier):
tier.laut()
tier_laut_machen(Vogel())
tier_laut_machen(Ente())
tier_laut_machen(Hund("Bello")) # Funktioniert auch!
Piep piep!
Quak quak!
Bello bellt: Wau wau!
Tipp: Python bevorzugt Duck-Typing ("If it walks like a duck...") – Sie müssen keine expliziten Interfaces definieren. Das macht den Code flexibel, kann aber auch zu Laufzeitfehlern führen.

Dunder-Methoden – Magic Methods (__xxx__)

__str__ · __repr__ · __len__ · __add__
def __str__(self): return f"Person: {self.name}" print(obj) # Ruft __str__ auf

Dunder-Methoden (Double UNDERscore) sind spezielle Methoden, die von Python automatisch aufgerufen werden – z.B. bei print(), len() oder Operatoren.

Wichtige Dunder-Methoden

Methode Beschreibung
__str__ String-Repräsentation für Benutzer (print())
__repr__ String-Repräsentation für Entwickler (debug)
__len__ Länge für len()
__add__ Addition (+)
__eq__ Gleichheit (==)
__lt__ Kleiner als (<) für Sortierung
__call__ Objekt wie eine Funktion aufrufen
__enter__ / __exit__ Context Manager (with Statement)
Beispiele
class Buch:
def __init__(self, titel, autor, seiten):
self.titel = titel
self.autor = autor
self.seiten = seiten
def __str__(self):
return f"{self.titel} von {self.autor}"
def __len__(self):
return self.seiten
def __add__(self, other):
return self.seiten + other.seiten
b1 = Buch("Python 101", "Max", 300)
b2 = Buch("Datenbanken", "Anna", 250)
print(b1) # __str__
print(len(b1)) # __len__
print(b1 + b2) # __add__
Python 101 von Max
300
550
Tipp: Immer __str__ und __repr__ implementieren – __str__ für die Benutzer, __repr__ für die Debug-Ausgabe (oft reicht __repr__ = __str__).

@property – Getter, Setter, Deleter

@property · @name.setter · @name.deleter
@property def name(self): return self._name @name.setter def name(self, value): self._name = value

@property ermöglicht den Zugriff auf Attribute wie auf eine Variable, aber mit Kontrolle (Validierung, Berechnung). Setter und Deleter erlauben zusätzliche Logik.

Beispiele
class Person:
def __init__(self, name, alter):
self._name = name
self._alter = alter
@property
def alter(self):
return self._alter
@alter.setter
def alter(self, value):
if value < 0:
raise ValueError("Alter kann nicht negativ sein")
self._alter = value
@property
def name(self):
return self._name.title()
p = Person("max", 30)
print(p.name) # "Max" (automatisch formatiert)
p.alter = 35 # Setter validiert
# p.alter = -5 # würde ValueError auslösen
Max
Tipp: Verwenden Sie @property, um den direkten Zugriff auf Attribute zu kontrollieren – z.B. für Validierung, Formatierung oder Berechnung von Werten.

Python OOP im Überblick

class Blaupause für Objekte
class Auto:
__init__ Konstruktor
self, Attribute
Vererbung Eltern-Kind-Hierarchie
class Kind(Eltern)
Polymorphie Viele Formen, gleiche Schnittstelle
obj.methode()
Dunder Magic Methods
__str__, __len__
@property Getter/Setter
Kontrollierter Zugriff

Quick Summary

class
Klasse definieren
__init__
Konstruktor
Vererbung
Eltern-Kind
Polymorphie
Viele Formen
__str__
Magic Method
@property
Getter/Setter
class Person: def __init__(self, name): self.name = name · class Student(Person): ...