Appearance
Kapitel 15: Objektorientierte Programmierung (OOP)
🎯 Lernziele
In diesem Kapitel lernst du:
- Was Objektorientierte Programmierung (OOP) ist
- Klassen und Objekte zu erstellen
- Konstruktoren (
__init__) zu verwenden - Vererbung (Inheritance) zu nutzen
- Vorteile von OOP zu verstehen
15.1 Was ist OOP?
🤔 Warum OOP?
Problem ohne OOP (Prozedurale Programmierung):
python
# Variablen für eine Person
name = "Max"
alter = 25
email = "max@example.com"
# Funktionen
def begüß(person_name):
print(f"Hallo {person_name}!")
begüß(name)Lösung mit OOP:
python
class Person:
def __init__(self, name, alter):
self.name = name
self.alter = alter
def begüß(self):
print(f"Hallo {self.name}!")
# Objekt erstellen
p = Person("Max", 25)
p.begüß()🎁 Vorteile von OOP
- ✅ Code-Organisation: Alles, was zusammengehört, ist in einer Klasse
- ✅ Wiederverwendbarkeit: Klassen können wiederverwendet werden
- ✅ Vererbung: Eigenschaften und Methoden können weitergegeben werden
- ✅ Datenkapselung: Daten werden vor direktem Zugriff geschützt
15.2 Klassen und Objekte
📦 Klasse (Class)
Eine Klasse ist ein Bauplan für Objekte.
python
# Klasse definieren
class Person:
# Klassenattribute (alle Objekte teilen sich diese)
spezies = "Mensch"
# Instanzattribute (jedes Objekt hat seine eigenen)
def __init__(self, name, alter):
self.name = name
self.alter = alter
# Methode
def vorstellen(self):
print(f"Ich heiße {self.name} und bin {self.alter} Jahre alt.")🏠 Objekt (Instanz)
Ein Objekt ist eine Instanz einer Klasse.
python
# Objekte erstellen (Instanziierung)
p1 = Person("Max", 25)
p2 = Person("Anna", 22)
# Methoden aufrufen
p1.vorstellen() # Ich heiße Max und bin 25 Jahre alt.
p2.vorstellen() # Ich heiße Anna und bin 22 Jahre alt.
# Attribute zugreifen
print(p1.name) # Max
print(p2.alter) # 22
print(Person.spezies) # Mensch15.3 Der Konstruktor (__init__)
🔨 __init__()-Methode
Der Konstruktor wird automatisch aufgerufen, wenn ein Objekt erstellt wird.
python
class Person:
def __init__(self, name, alter):
# self bezieht sich auf das aktuelle Objekt
self.name = name # Instanzattribut
self.alter = alter # Instanzattribut
print(f"Person {name} erstellt!")
# Beim Erstellen des Objekts wird __init__() aufgerufen
p = Person("Max", 25)
# Ausgabe: Person Max erstellt!💡 Wichtig: self
selfbezieht sich auf das aktuelle Objekt- Muss als erstes Argument in Methoden stehen
- Muss nicht beim Aufruf der Methode übergeben werden!
python
class Person:
def __init__(self, name): # self ist das erste Argument
self.name = name
def sag_name(self): # self ist das erste Argument
print(self.name)
p = Person("Max")
p.sag_name() # Nicht p.sag_name(self) aufrufen!15.4 Vererbung (Inheritance)
🧬 Grundlegendes Konzept
Vererbung erlaubt es, eine Klasse zu erstellen, die Eigenschaften und Methoden einer anderen Klasse übernimmt.
python
# Elternklasse (Basis-/Superklasse)
class Tier:
def __init__(self, name):
self.name = name
def essen(self):
print(f"{self.name} isst.")
# Kindklasse (Abgeleitete Klasse)
class Hund(Tier): # Tier wird vererbt
def bellen(self):
print(f"{self.name} bellt: Wuff!")
class Katze(Tier): # Tier wird vererbt
def miauen(self):
print(f"{self.name} miaut: Miau!")
# Verwenden
hund = Hund("Bello")
hund.essen() # Geerbte Methode
hund.bellen() # Eigene Methode
katze = Katze("Mizi")
katze.essen() # Geerbte Methode
katze.miauen() # Eigene Methode🔁 Methoden überschreiben (Override)
python
class Tier:
def geräusch(self):
print("Tier macht ein Geräusch")
class Hund(Tier):
def geräusch(self): # Methode überschreiben
print("Hund bellt: Wuff!")
class Katze(Tier):
def geräusch(self): # Methode überschreiben
print("Katze miaut: Miau!")
# Polymorphismus
tiere = [Hund("Bello"), Katze("Mizi")]
for tier in tiere:
tier.geräusch()
# Ausgabe:
# Hund bellt: Wuff!
# Katze miaut: Miau!🔗 super() verwenden
python
class Tier:
def __init__(self, name):
self.name = name
print(f"Tier {name} erstellt.")
class Hund(Tier):
def __init__(self, name, rasse):
super().__init__(name) # Ruft den Konstruktor der Elternklasse auf
self.rasse = rasse
print(f"Hund der Rasse {rasse} erstellt.")
h = Hund("Bello", "Labrador")
# Ausgabe:
# Tier Bello erstellt.
# Hund der Rasse Labrador erstellt.15.5 Weitere OOP-Konzepte
🔒 Datenkapselung (Encapsulation)
python
class Person:
def __init__(self, name, alter):
self.name = name
self.__alter = alter # Privates Attribut (durch __)
def geburtstag(self):
self.__alter += 1
def get_alter(self): # Getter-Methode
return self.__alter
p = Person("Max", 25)
# print(p.__alter) # AttributeError! (Nicht von außen zugreifbar)
p.geburtstag()
print(p.get_alter()) # 26🎨 Polymorphismus
python
class Form:
def fläche(self):
pass
class Rechteck(Form):
def __init__(self, breite, höhe):
self.breite = breite
self.höhe = höhe
def fläche(self):
return self.breite * self.höhe
class Kreis(Form):
def __init__(self, radius):
self.radius = radius
def fläche(self):
return 3.14 * self.radius ** 2
# Polymorphismus
formen = [Rechteck(5, 3), Kreis(4)]
for form in formen:
print(f"Fläche: {form.fläche()}")15.6 Praxisbeispiel: Bankkonto
python
class Bankkonto:
def __init__(self, inhaber, kontonummer):
self.inhaber = inhaber
self.kontonummer = kontonummer
self.__stand = 0.0 # Privates Attribut
def einzahlen(self, betrag):
if betrag > 0:
self.__stand += betrag
print(f"{betrag}€ eingezahlt.")
else:
print("Betrag muss positiv sein!")
def auszahlen(self, betrag):
if 0 < betrag <= self.__stand:
self.__stand -= betrag
print(f"{betrag}€ ausgezahlt.")
else:
print("Unzureichender Stand oder ungültiger Betrag!")
def zeige_stand(self):
print(f"Kontostand: {self.__stand:.2f}€")
# Verwenden
konto = Bankkonto("Max Mustermann", "DE123456")
konto.einzahlen(100)
konto.auszahlen(30)
konto.zeige_stand() # Kontostand: 70.00€⚠️ Häufige Fehler
❌ Fehler 1: self vergessen
python
# Falsch
class Person:
def __init__(name): # self fehlt!
pass
# Richtig
class Person:
def __init__(self, name): # self ist das erste Argument
self.name = name❌ Fehler 2: __init__ falsch buchstabieren
python
# Falsch (wird nicht als Konstruktor erkannt)
class Person:
def __int__(self, name): # Falsch buchstabiert!
pass
# Richtig
class Person:
def __init__(self, name): # Doppelter Unterstrich!
self.name = name❌ Fehler 3: Auf private Attribute von außen zugreifen
python
class Person:
def __init__(self, name):
self.__name = name
p = Person("Max")
# print(p.__name) # AttributeError!
# Richtig: Getter-Methode verwenden
class Person:
def get_name(self):
return self.__name📝 Zusammenfassung
In diesem Kapitel hast du gelernt:
- ✅ Was Objektorientierte Programmierung (OOP) ist
- ✅ Klassen und Objekte zu erstellen
- ✅ Den Konstruktor (
__init__) zu verwenden - ✅ Vererbung (Inheritance) zu nutzen
- ✅ Methoden zu überschreiben
- ✅
super()zu verwenden - ✅ Datenkapselung anzuwenden
🎯 Übung
- Erstelle eine Klasse
Fahrzeugmit den Attributenmarke,modellundbaujahr. - Erstelle eine abgeleitete Klasse
Auto, die vonFahrzeugerbt und das Attributanzahl_türenhinzufügt. - Überschreibe eine Methode
beschreib()in den Kindklassen. - Erstelle eine Klasse
Bruchmit den Attributenzählerundnenner. Implementiere Methoden für Addition und Multiplikation.
⏭️ Nächstes Kapitel
In Kapitel 16 werden wir Praxis-Projekte durchführen und das Gelernte anwenden!
