drei gezeichnete Schafe

Objekte und Klassen



Quellen: M. Brenner, J. Schnaiter, "Softwareentwicklung mit Python", ZSL Freiburg, 2024

Python ist eine objektorientierte Programmiersprache. Objekte haben Eigenschaften (engl. states) und Fähigkeiten (engl. behaviors). Eine Klasse beschreibt, welche Eigenschaften und Fähigkeiten ein Objekt haben darf und stellt somit den Bauplan für jedes Objekt.

In diesem Artikel lernst Du den Aufbau von Objekten und Klassen und deren Anwendung kennen.

1 Klassen und Objekte und deren Eigenschaften - Attribute

Zeichnung zweier unterschiedlicher Schafe

Stellen wir uns eine Herde vor, die aus vielen Schafen besteht. Dabei unterscheidet sich jedes Schaf in seinen Eigenschaften (Attribute) wie Name, Alter und Gewicht.

Jedes dieser Tiere gehört nun zur Gruppe der Schafe: Wir sprechen von der Klasse Schaf. Ein Schaf mit dem Namen Emma, 20 Jahre und 40.3 kg ist ein Objekt (Instanz) der Klasse Schaf. Diesen Bauplan den eine Klasse für Objekte bereitstellt kann man in einer Tabelle darstellen:

Objektnr. Name Alter Gewicht
0000 Emma 20 40.3
0001 Berta 12 25.0

Code für die Klasse Schaf

Wir definieren nun unsere erste Klasse Schaf. Jede Klasse beginnt mit dem Schlüsselwort class und dem Klassennamen (hier Schaf). Dabei ist darauf zu achten, dass der Klassenname mit einem Großbuchstaben beginnt.

Um nun Anfangswerte zu setzten verwendet man die Methode def __init__(self, ...). Diese Methode wird immer dann aufgerufen wenn eine neue Instanz angelegt wird. Somit können alle Attributwerte eines Objekts initialisiert werden.

#meine erste Klasse
class Schaf:
  def __init__(self, name = "anyname", alter = 1, gewicht = 2.5):
    self.name = name
    self.alter = alter
    self.gewicht = gewicht

#meine zweite Klasse
class Schafherde:
  #Erzeuge meine ersten Objekte
  s1 = Schaf("Emma", 20, 40.3)
  s2 = Schaf(alter=3)

  #Zeige meine ersten Objekte an
  print(f"{s1.name}: ⌛ {s1.alter} Jahre + ⚖ {s1.gewicht} kg")
  print(f"{s2.name}: ⌛ {s2.alter} Jahre + ⚖ {s2.gewicht} kg")  

Erzeugen von Objekten, Eigenschaften zuweisen und ausgeben

Wir definieren unsere zweite Klasse Schafherde. In dieser werden einzelne Schafe als Objekte erzeugt, Attribute zugewiesen und die Werte ausgegeben.

Um in dieser Klasse ein Schaf zu erzeugen, wird nun die Klasse Schaf aufgerufen und Parameter aus dem Konstruktor als Startwerte mitgegeben. Das Schaf selbst wird als Variable abgespeichert, hat nun aber drei Eigenschaften: Name, Alter und Gewicht.

Abschließend können wir mit Hilfe des Objektnamens und mit Hilfe des Punktoperators auf die Eigenschaften der Objekte zugreifen (z.B. s1.alter).

Aufgabe 1 Die Schafherde

Erstelle die Klasse Schaf und Schafherde.

  1. Lege ein neues Notebook Schafherde.ipynb im Ordner "10-Objektorientierung" an.
  2. Erstelle die Klasse Schaf und deklariere drei Attribute (Eigenschaften). Achte darauf, dass du drei verschiedene Datentypen verwendest: String, int, double und jedem Wert einem Standardwert (engl. default argument) mitgibst.
  3. Erstelle die Klasse Schafherde. Erzeuge drei Schafe als Objekte (Instanzen) und weise jedem Schaf jeden Attributwert zu. Gib eine Liste der Werte für jedes Schaf aus.
  4. Füge ein weiteres Attribut boolean geschlecht hinzu. Lass den Benutzer wählen, ob er die Mutterschafe oder Schafböcke gelistet haben möchte.

    Wähle weiblich für True und männlich für False.

Schafherde

Die Ausgabe sollte bspw. wie folgt aussehen:

Folgende Mutterschafe sind in der Herde:
Emma: ⌛ 20 Jahre + ⚖ 40.3 kg
anyname: ⌛ 3 Jahre + ⚖ 2.5 kg

Folgende Schafböcke sind in der Herde:
Günter: ⌛ 12 Jahre + ⚖ 62.0 kg


Aufgabe 2 Der Fuhrpark

Erstelle die Klasse Auto und Fuhrpark.

zwei Autos
  1. Erstelle die Klasse Auto und deklariere folgende Attribute (Eigenschaften) mit Standardwert des angegebenen Datentyps:
    String marke,
    String modell,
    String farbe,
    int leistung,
    double LiterPro100km,
    double tankstand,
    boolean tankwarnung.
  2. Erstelle die Klasse Fuhrpark. Erzeuge zwei Autos als Objekte und weise jedem Auto jeden Attributwert zu. Gib eine Liste der Werte für jedes Auto aus.
  3. Bei einem Tankstand unter 10 l, setze tankwarnung = True, empfehle das Tanken und gib in Abhängigkeit des Spritverbrauchs die Reichweite aus.

Die Ausgabe sollte wie folgt aussehen:

Marke: VW
Typ: Polo
Verbrauch: 4.7 l/100 km
Tankstand: 3.2 l

Sie sollten tanken. Ihre Reichweite beträgt noch 68 km.


2 Klassen und Objekte und deren Fähigkeiten - Methoden

Methoden: Die Fähigkeiten der Klassen

Objekte haben auch Fähigkeiten, welche in der Klasse als Methoden definiert werden. Wir haben bereits die fest verankerte Methode def __init__(self, ...), den sogenannten Konstruktor, kennen gelernt.

Wir können auch eigene Methoden schreiben. Damit ein Schaf bspw. einen Laut geben kann, definieren wir folgende Methode in der Klasse Schaf:

def gebenLaut(self):
  print("mäh...")

Der Methodenaufruf in der Klasse Schafherde ist objektgebunden und erfolgt mit dem Punktoperator.

s1.gebenLaut()
Zeichnung zweier Schafe mit Fähigkeiten

Methoden mit Parameter erstellen

def fressenGras(self, menge = 1):
  self.gewicht += menge*0.5
  if(menge >= 1):
    print("yummy...")
def erhalteGewicht(self):
  print("Ich gebe was zurück.")
  return self.gewicht

Möchte man ein Schaf Gras fressen lassen, ist es sinnvoll die Menge als Parameter zu übergeben. In der Methode kann man dann beispielsweise eine Gewichtszunahme in Abhängigkeit von der Grasmenge berechnen.

Und noch ein Hinweis: Das Vorgeben von Standardwerten (engl. default arguments) macht das früher verwendete "Überladen von Methoden" hinfällig.

To-String-Methode

Eine weitere fest verankerte Methode ist die sogenannte to-String-Methode def __str__(self). Sie gibt einen String mit allen Eigenschaften des Objekts zurück. Durch den Aufruf des Parameters self.__class__.__name__ wird der Klassenname als String erzeugt.

Der Aufruf der Methode erfolgt einfach über print(s1). Ohne die to-String-Methode würden wir durch den Aufruf ldediglich die Adresse des Objekts erhalten.

def __str__(self):
  return self.__class__.__name__ 
    + f" {self.name}: ⌛ {self.alter} Jahre 
    + ⚖ {self.gewicht} kg"

Aufgabe 3 Ordne zu

Ideen: Klasse EFS222
Ordne die korrekte Antwort zu.

Erzeuge ein neues Objekt.
Wähle zwei Antworten.

  1. a1 = Auto()
  2. Auto a1 = new Auto()
  3. a2 = Auto(ps = 120)
  4. a2 = new Auto()

Erkläre den Begriff "Attribut".
Wähle eine Antwort.

  1. Eigenschaften von Python
  2. verschiedene Datentypen (String, int, double etc.)
  3. die Deklaration von Methoden
  4. Eigenschaften von Objekten

Die Klasse Schaf soll einen Konstruktor mit den beiden Parametern name und gewicht erhalten. Finde die Anzahl der Fehler im folgenden Quelltext.

class Schaf:
  def _init_(name="any",gewicht=2,0):
    self.name = name
    self.gewicht = gewicht

Der Konstruktor der Klasse Auto hat die beiden vordefinierten Parameter marke und ps. Finde die Anzahl der korrekten Objekt­erzeugungen.

  a1 = Auto()
  a2 = Auto("VW",200)
  a3 = Auto(200,"Audi")
  a4 = Auto(ps = 200)

Bestimme die zugehörige Methode, zum Methodenaufruf s1.fressenGras(4). Wähle eine Antwort.

  1. def fressenGras(self, x, y): ...
  2. class fressenGras def: ...
  3. def fressenGras(self, x = 0): ...
  4. return fressenGras(self, menge)...

Bestimme den Zweck des Schlüsselworts return in Methoden.
Wähle eine Antwort.

  1. Die Methode gibt einen Wert zurück.
  2. Die Methode gibt keinen Wert zurück.
  3. Die Methode ruft sich selber erneut auf.
  4. Es kennzeichnet die Methode als private

Welchen Zweck erfüllt die to-string-Methode def __str__(self): ...
Wähle eine Antwort.

  1. bearbeitet Methoden die zu häufig aufgerufen wurden
  2. streicht fehlerhafte Objekte
  3. die Methode gibt es nicht in Python
  4. liefert einen String mit allen Eigenschaften des Objekts

Bestimme den Zweck der Referenzvariable self in Python.
Wähle eine Antwort.

  1. sie ist bloß zwecks der Schönheit des Codes da
  2. wird verwendet, um auf Attributwerte eines Objekts zurückzugreifen
  3. wird verwendet um auf eine andere Klasse zu referenzieren
  4. schließt das entsprechende Attribut aus der eigenen Klasse

Aufgabe 4 Fähigkeiten der Schafe

Die Schafe sollen mit Fähigkeiten ausgestattet werden.

  1. Erweitere die Klasse Schaf mit den vier folgenden Methoden:
    def gebenLaut (self):,
    def fressen(self, mengeGras=0, mengeKohl=0):,
    def erhalteGewicht(self):,
    def __str__(self): ...
  2. Teste in der Klasse Schafherde die neuen Funktionen ausführlich. Lass alle Änderungen der Attribute jeweils anzeigen.
  3. Erfinde für die Klasse Schaf eine weitere Funktionalität, welche das Niveau Deiner Objekte verbessert.
Zeichnung zweier Schafe

Die Lösung sollte bspw. folgendermaßen aussehen:

Das weiße Schaf Emma sagt: Mäh!
Das weiße Schaf Emma wiegt 50.0kg.
Das braune Schaf Berta sagt: Mäh!

Das Schaf Emma frisst 5 kg Gras.
Das weiße Schaf Emma wiegt 51.5kg.

Das Schaf Emma frisst 2 kg Gras und 5 kg Kohl.
Das weiße Schaf Emma wiegt 55.6kg.

Entspann dich erstmal ...



Ameisen in Thailand

In Hamburg lebten zwei Ameisen,
Die wollten nach Australien reisen.
Bei Altona auf der Chaussee,
Da taten ihnen die Beine weh,
Und da verzichteten sie weise
Dann auf den letzten Teil der Reise.

Aufgabe 5 Fähigkeiten der Autos

Die PKW's sollen mit Fähigkeiten ausgestattet werden.

  1. Erweitere die Klasse Auto mit den folgenden Methoden:
    def fahrenStrecke (self, km = 0): ..,
    def tanken(self, menge = 1): ..,
    def erhalteReichweite(self): ..,
    def __str__(self):
  2. Teste in der Klasse Fuhrpark die neuen Funktionen ausführlich. Lass alle Änderungen der Attribute jeweils anzeigen.
  3. Wiederhole in einer Schleife die Distanzabfrage solange, bis der Nutzer den Wert 0 eingibt. Bei einem Tankstand von weniger als 10 l wird eine Tankwarnung angezeigt und die Möglichkeit zum Tanken gegeben.
Zeichnung zweier Autos

Die Lösung sollte bspw. folgendermaßen aussehen:

Ihnen steht folgendes Autos zur Verfügung:
Mercedes GLS metallic schwarz
Leistung: 230 PS
Verbrauch: 12.4 l/100km
Tankstand: 20.0 l

Welche Distanz wollen Sie mit dem Mercedes zurücklegen? 100
Fahrstrecke: 100 km
Verbrauch: 12.4 l
Neuer Tankstand: 7.6 l Wollen Sie tanken (j/n)? j
Ihr neuer Tankstand: 17.6 l

3 Objekte in Listen speichern - Automatisierte Objektauswertung

Da die Objektnamen keinerlei Bedeutung haben, speichert man die verschiedenen Objekte direkt beim Erzeugen in einer Liste. Der große Vorteil der dadurch entsteht: Es können mit Hilfe von Schleifen automatisierte Ausgaben und Auswertungen aller Objekte generiert werden.

Mit der append(..)-Methode wird ein Element der Liste hinzugefügt.

class Schafherde:
  schafliste = []

  #drei neue Schafe erzeugen
  schafliste.append(Schaf("Emma", 20, 40.3))
  schafliste.append(Schaf(alter = 3))
  schafliste.append(Schaf())

  #8 neue Schafe mit vorgegebenen Namen erzeugen und in der Schafliste abspeichern
  schafnamen = ["Emma", "Berta", "Schaun", "Alma", "Elias", "Uwe", "Sven", "Roman"]
  for i in schafnamen:
    schafliste.append(Schaf(i))
Zeichnung zweier Schafe

Automatisierte Ausgabe und Auswertung

In der for-each-Schleife werden alle Elemente der Liste abgefragt. for-each-Schleifen iterrieren über alle Daten­strukturen deren Elemente aufzählbar sind. Für die nummerierte Ausgabe, verwendet man die enumerate(..) Methode.

Für die Berechnung des Mittelwerts addiert man mit Hilfe einer for-each-Schleife alle Werte und teilt diese durch die Anzahl der Werte. Um die Anzahl der Listenelemente zu ermitteln kommt die len(..)-Methode zum Einsatz.

class Schafherde:
...
  #Ausgabe aller Schafe
  for schaf in schafliste:
    print(schaf)

  #nummerierte Ausgabe aller Schafe
  for i, schaf in enumerate(schafliste):
    print(i+1, schaf)

  #Berechnung des mittleren Herdenalters
  gesamt = 0		
  for schaf in schafliste:
    gesamt += schaf.alter
  print(f"Mittleres Herdenalter: {gesamt/len(schafliste)}")

Aufgabe 7 Bücherei

Realisiere eine Bücherei in der Bücher mit Titel, Autor und Bewertung gespeichert werden sollen.

Bücherstapel
  1. Erstelle das Klassenpaar Book und Library.
  2. Füge zur Klasse Book die Attribute title, author, rating hinzu.
  3. Speicher in Klasse Library eine Liste mit Buchobjekten booklist und erzeuge drei Einträge wie bspw. booklist.append(Book("Herr der Ringe", "J.R.R. Tolkien", 4.8));.
  4. Gib alle Einträge aus.
  5. Berechne die durchschnittliche Bewertung aller Bücher.
  6. Schreibe eine Methode zur Bewertung der Bücher.
  7. Erzeuge eine zufällige Bewertung beim Anlegen neuer Bücher.
  8. Berechne den Median der Bewertungen.
  9. Beurteile, wann der Einsatz eines Mittelwertes und wann der Einsatz des Medians sinnvoll ist.

Wortliste und Satzbausteine



das Objekt, -e Objekte haben Eigenschaften (engl. states) und Fähigkeiten (engl. behaviors). Diese werden in einer zugehörigen Klasse festgelegt.
die Klasse, -n Eine Klasse beschreibt, welche Eigenschaften und Fähigkeiten ein Objekt haben darf und stellt somit den Bauplan von Objekten bereit.
die Fähigkeit, -en Fähigkeiten von Objekten werden in Methoden beschrieben.
die Eigenschaft, -en Eigenschaften von Objekten werden in Attributen/Variablen festgelegt.
der Standard­wert, -e Parameter einer Methoden können einen Standardwert (engl. default argument) erhalten. Dadurch wird das Überladen von Methoden hinfällig.
das Überladen einer Methode Existieren mehrere Methoden gleichen Namens spricht man vom Überladen. Dabei muss die Signatur eindeutig sein. In Python erübrigt sich das Über­laden dank des Standard­wertes
die Signatur, -en Methodenname und Parameter einer Methode.
die Parameter­liste, -n eine Liste von Variablennamen, welche beim Methodenaufruf übergeben werden