===== Objekte und Klassen in Python ===== Mit Methoden hast du bereits ein Verfahren kennengelernt, um häufig benötigte Programmschritte innerhalb eines Programmes zusammenzufassen. Methoden haben aber noch weitere Vorteile: * Sie vereinfachen die Wartbarkeit des Codes, da Fehler innerhalb einer Methode gut eingegrenzt werden können und die Fehlerkorrektur dann an allen Stellen im Programm wirkt, an denen sie zum Einsatz kommen * Sie ermöglichen die Zusammenarbeit in einem Team, z.B. könnte man überlegen, welche Methoden mit welchen Parametern für eine Aufgabe benötigt werden und diese Methoden dann von unterschiedlichen Personen bearbeiten lassen Objekte perfektionieren diese Vorteile noch einmal auf einem ganz anderen Level. Objekte und Klassen klingen als Begriffe erstmal sehr abstrakt, aber eigentlich sind diese intuitiv gut zugänglich. Dazu ein Beispiel: In einer Schul**klasse** gibt es Schüler:innen. Man sagt: Schüler:innen sind **Objekte** der Klasse (vielleicht fühlst du dich manchmal ja auch als bloßes Objekt in der Schule). Klassen erzeugst du in Python so (tut gar nicht weh): class schueler: pass Das "pass" kannst du erstmal als Hilfe sehen. Es sagt dem Interpreter: "Ist noch nicht fertig, meckere vorerst nicht!". Schüler:innen haben bestimmte Eigenschaften. Eigenschaften bezeichnet man beim Programmieren auch als **Attribute**. Wir machen es uns einfach und nehmen uns einige Beispielattribute heraus, die sich gut für das Programmieren eignen. * Name * Geschlecht * Haarfarbe * Durchschnittsnote Diese Attribute werden für alle Objekte einer Klasse festgelegt. Es ist guter Stil, dafür zu sorgen, dass keine Objekte ohne Attribute erzeugt werden können. Beim Bauen ("Konstruieren") eines Objekts kann man das durch einen Konstruktor beim Anlegen **init()** erzwingen (tut etwas mehr weh). class schueler: # Attribute definieren ("self" nicht vergessen!") def __init__(self, name, geschlecht, haarfarbe, durchschnittsnote): self.name = name self.geschlecht = geschlecht self.haarfarbe = haarfarbe self.durchschnittsnote = durchschnittsnote Jetzt können wir schon Schüler:innen erzeugen - das Schlüsselwort "**self**" sagt, dass sich die laufende Operation auf das aktuelle Objekt bezieht (du könntest ja innerhalb eines Objektes auch auf andere Objekte zugreifen, s.u.). Nochmal zum Mitdenken: self.geschlecht = geschlecht Heißt: Hallo Objekt! Dein eigenes Attribut ("self") "geschlecht" setzt du auf den Wert, den dir dein Meister/deine Meisterin beim Anlegen übergeben hat. Jetzt bauen wird uns mal zwei Schüler:innen (tut fast nicht weh). class schueler: # Attribute definieren def __init__(self, name, geschlecht, haarfarbe, durchschnittsnote): self.name = name self.geschlecht = geschlecht self.haarfarbe = haarfarbe self.durchschnittsnote = durchschnittsnote # main schueler01 = schueler("Maik", "m", "grau", 2.3) schueler02 = schueler("Kerstin", "w", "braun", 1.1) Na, toll, jetzt haben wir zwei Schüler:innen erzeugt. Man sollte damit aber auch etwas anfangen können. Man kann z.B. die Attribute eines Objekts ausgeben, indem man das gewünschte Attribut mit einem Punkt hinter den Namen des Schuelerobjekts hängt. In anderen Programmiersprachen müsstest du dafür "Getter"-Methoden definieren, Python macht das freundlicherweise automatisch für dich. class schueler: # Attribute definieren def __init__(self, name, geschlecht, haarfarbe, durchschnittsnote): self.name = name self.geschlecht = geschlecht self.haarfarbe = haarfarbe self.durchschnittsnote = durchschnittsnote # main schueler01 = schueler("Maik", "m", "grau", 2.3) schueler02 = schueler("Kerstin", "w", "braun", 1.1) print(schueler01.name) Man kann aber auch Attribute von Objekten vergleichen: class schueler: # Attribute definieren def __init__(self, name, geschlecht, haarfarbe, durchschnittsnote): self.name = name self.geschlecht = geschlecht self.haarfarbe = haarfarbe self.durchschnittsnote = durchschnittsnote # main schueler01 = schueler("Maik", "m", "grau", 2.3) schueler02 = schueler("Kerstin", "w", "braun", 1.1) if schueler01.durchschnittsnote < schuler02.durchschnittsnote: print(f'{schueler01.name} ist der bessere Schüler!') else: print(f'{schueler02.name} ist der bessere Schüler!') === Attribute verändern === Durchschnittsnote und Haarfarbe können sich im Leben mal ändern. Hat man ein Objekt erstmal erzeugt, kommt man so ohne Weiteres nicht mehr an die Attribute heran. Man kann diese nicht einfach überschreiben, es sei denn, das Objekt selbst bietet uns dafür eine sogenannte "Setter"-Methode an. class schueler: # Attribute definieren def __init__(self, name, geschlecht, haarfarbe, durchschnittsnote): self.name = name self.geschlecht = geschlecht self.haarfarbe = haarfarbe self.durchschnittsnote = durchschnittsnote # Settermethoden definieren def setGeschlecht(self, geschlecht): self.geschlecht = geschlecht def setHaarfarbe(self, haarfarbe): self.haarfarbe = haarfarbe # main schueler01 = schueler("Maik", "m", "grau", 2.3) print(schueler01.haarfarbe) schueler01.setHaarfarbe("getönt") print(schueler01.haarfarbe) Auf die Methoden eines Objekts greifst du genau so zu, wie auf die Attribute. Du machst quasi einen ganz normalen Methodenaufruf, sagst aber vorher, auf welches Objekt sich das beziehen soll. Genau wie Attribute stehen Methoden für alle Objekte einer Klasse zur Verfügung. === Kapselung === Der Trick hinter der Setter-Methode ist das Prinzip der Kapselung. Derjenige, der ein Objekt verwendet, muss nur wissen, welche Attribute und Methoden es gibt, aber nicht zwingend, wie diese programmiert sind, wenn sie denn fehlerfrei funktionieren. Man sagt: Die Prozeduren in einem Objekt sind **"gekapselt"**. === In einer Klasse ist alles Attribut oder Methode === Es gibt in einer Klasse kein Hauptprogramm. Nur Attribut- und Methodendefinitionen sind zulässig!