Klassen und Objekte

Sensoren am Ergometer
🎯 Lernziele
Nach dieser Einheit sind Sie in der Lage dazu * Klassen und Objekte im Sinne der Objektorientierten Programmierung zu beschreiben * Klassen mit Attributen und Methoden in Python anzulegen
Objekte
- Objektorientierte Programmierung: Programmierparadigma mit Fokus auf Objekte, deren Eigenschaften und Fähigkeiten
- z.B. Objekt der Klasse Sensor
- Attribute (Eigenschaften):
- Zählernummer
- Aktueller Messwert
- Liste bisheriger Messwerte
- Methoden:
- Mittelwert bilden
- Messen
- Letzten Messwert übermitteln
Klassen
- Die Klasse Sensor ist eine abstrakte Beschreibung aller denkbaren Objekte vom Typ Sensor
- Ein konkretes Objekt der Sensor ist eine Instanz (Ausprägung) der Klasse Sensor
Objektorientierte Programmierung
- Aufbauend auf strukturierter Programmierung (
if-else,for,function()) - Fokus erst auf das was (Objekte) dann erst auf das wie (Algorithmen, Funktionen, Datenstrukturen)
- Erleichtert den Einsatz von komplexem Code und Austausch zwischen Entwickler:innen und Anwender:innen
Objekte als Instanzen von Klassen

- Objekte sind Instanzen (Ausprägungen) einer Klasse
- Eine Klasse beschreibt die Eigenschaften (Attribute) und die Tätigkeiten (Methoden), die ein Objekt der Klasse später besitzen kann.
Attribute und Methoden

- Die Attribute sind Variablen entweder mit elementaren Datentypen (int, str, float) oder wiederum Klassen
- Die Methoden sind (kleine) Algorithmen, die im Sinne der strukturierten Programmierung implementiert werden müssen (Prozeduren und Funktionen)
Umsetzung in Code
-
Eine Klasse ist das allgemeine Beschreibung einer Klasse von Objekten:
# Python class Pferd(): # Definition des Konstruktors = Beschreibung der Klasse def __init__(self, groesse, hoechstgeschwindigkeit): self.groesse = groesse self.hoechstgeschwindigkeit = hoechstgeschwindigkeit self.geschwindigkeit = 0 -
Die Methode
__init__ist der Konstruktor und wird aufgerufen, sobald ein Objekt einer Klasse instanziiert wird - Jeder Methode eines Objektes wird der Parameter
selfübergeben, welcher aus das Objekt selbst referenziert - Hier wird beispielsweise ein Objekt mit den Attributen
groesseundgeschwindigkeiterzeugt.
Objekte und Klassen 🧠
- Ein Objekt ist eine spezielle Ausprägung einer Klasse
-
Um mit einer Klasse zu arbeiten werden Objekte der Klasse instanziiert
# Aufruf des Konstruktors = Instanziierung des Objekts black = Pferd("140 cm", '30 kmh') beauty = Pferd("150 cm", '40 kmh') -
Die Klasse Pferd beschreibt allgemein das Verhalten jedes Pferdes!
- Hier werden zwei Objekte der Klasse Pferd angelegt
- Die beiden Pferde sind durch die Menge ihrer Attribute vollständig beschrieben
Methoden
- Prozeduren oder Funktionen einer Klasse
# Python
class Pferd():
# [...]
def laufen(self):
print("Läuft mit {}".format(self.geschwidigkeit))
# [...]
black = Pferd("140 cm", '30 km/h')
black.geschwindigkeit = '20 km/h'
black.laufen()
#> "Läuft mit 20 km/h"
Methoden & Funktionen
- Methoden sind Funktionen, die zu einer Klasse gehören
- Funktionen sind wieder aufrufbare Code-Einheiten, denen Argumente als Parameter übergeben werden können
- Funktionen geben einen Rückgabewert aus, der weiterverarbeitet werden kann
---
title:
---
classDiagram
class Sensor{
-int sensor_id
-float letzter_messwert
-string sensor_name
-[float] messwerte
-bilde_mittelwert()
-messe()
-uebermittle_messwert()
}
# Python
def bilde_mittelwert(list_of_measurements):
""" Eine Funktion, die eine Liste von Werten übernimmt und das arithmetische Mittel zurück gibt"""
mittelwert = sum(list_of_measurements) / len(list_of_measurements)
return mittelwert
ergebnis = bilde_mittelwert([1,2,3])
# Python
def <funktions_name>(<parameter>):
"""<Docstring: Kommentar zur Dokumentation>"""
<Berechnungen der Funktion>
return <Rückgabewert der Funktion>
Beispiel-Klasse Sensor
# Python
# Beschreibung einer Klasse as Python Code
class Sensor():
# Definition des Konstruktors, welcher ein Objekt der Klasse erzeugen kann
def __init__(self, sensor_id):
# Festlegung der Attribute
self.sensor_id = sensor_id
self.list_of_measurements = []
# Definition einer Methode
def bilde_mittelwert(self):
return sum(self.list_of_measurements) / len(self.list_of_measurements)
def messe(self, wert):
messwert = wert # wir nehmen an, der kommt irgendwo her
self.list_of_measurements.append(messwert)
return messwert
# Python
# Anlegen eines Objektes der Klasse Smart Meter
hr_sensor_1= Sensor(sensor_id = 123)
# Aufruf des Attributes meter_id des Objektes hr_sensor_1
print(hr_sensor_1.sensor_id)
# > 123
# Aufruf der Funktion messe des Objektes hr_sensor_1
hr_sensor_1.messe(2)
# Dem Attribut list_of_measurements wurde nun ein Element hinzugefügt
print(hr_sensor_1.list_of_measurements)
# > [2]
hr_sensor_1.messe(4)
print(hr_sensor_1.list_of_measurements)
# > [2,4]
print(hr_sensor_1.bilde_mittelwert())
# > 3.0
Zugriff auf Attribute
<object>.<attribute>#Python print(hr_sensor_1.sensor_id) # > 123- Objekte leben im Arbeitsspeicher

Kapselung (Geheimnisprinzip)
- Nicht alle Eigenschaften und Methoden eines Objektes müssen/sollten von außen sichtbar oder aufrufbar sein
- UML erlaubt die Modellierung folgender Zugriffsarten durch ein Zeichen vor dem Attributs- oder Methodennamen:
+public: Zugreifbar für alle (anderen) Objekte,-private: Nur für Objekte der eigenen Klasse zugreifbar,
---
title:
---
classDiagram
class Subject{
+ string name
- int __age
- __print_new_subject()
}
Beispiel Kapselung
- Das Alter der Versuchsperson soll von außen nicht sichtbar oder veränderbar sein. Entsprechend werden das Attribut
__ageund die Methode__print_new_subject()nach außen versteckt. - in Python geschieht dies über zwei vorangestellte
_
class Subject():
def __init__(self, name, age):
self.name = name
self.__age = age
def print_subject(self):
print("Created new subject {} with age {}!".format(self.name, self.__age) )
subject_1 = Subject("Bob", 35)
#> Created new subject Bob with age 35!
# subject_1.__age --> 'subject' object has no attribute '__age'
getter and setter
- sind Methoden, wie den Zugriff auf gekapselte Attribute ermöglichen
- ermöglicht Aufteilung zwischen read-only (nur getter) and write-only (nur getter)
- in anderen Programmiersprachen sehr üblich
class Subject():
def __init__(self,name, age):
self.__age = age
# Getter
def get_age(self):
return self.age
# Setter
def set_age(self, new_age):
self.age = new_age
subject_1 = subject("Bob", 35)
print(subject_1.get_age())
Sinnvolle Klassen
Kandidaten für Objekte und Klassen in der objektorientierten Analyse sind: - Ein Ding, das sichtbar und beschreibbar ist - Reale Dinge: Sensor, Ergometer, Fahrzeug... - Etwas, das man sich vorstellen kann - Rollen: Diagnostiker:in, Administrator:in, ... - Spezifikationen: Stufentest, Mittelwert... - Etwas, das in Taten umgesetzt werden kann oder etwas nicht Gegenständliches - Steuerungslogik, ...
✍️ Freiwillige Übungs-Aufgabe
🎯 Lernfortschritt
Nach dieser Einheit sind Sie in der Lage dazu * Klassen und Objekte im Sinne der Objektorientierten Programmierung zu beschreiben * Klassen mit Attributen und Methoden in Python anzulegen
🏆 Sakai-Aufgabe 6.1: Objektorientierung
- nutzen Sie das bestehende Repository aus Sakai-Aufgabe 3 & 5, um die Aufgabe zu bearbeiten. Damit Sie nun wieder unabhängig voneinander arbeiten können, erstellen Sie jeweils einen neuen Branch mit Ihrem Vornamen und arbeiten Sie alleine in diesem weiter.
- Committen Sie die stabile Lösungen und comitten Sie wieder mit der Commit-Message
Aufgabe61, wenn Sie den Code umgeschrieben haben. - erstellen Sie eine neue Datei
my_classes.pyin der Sie die KlassenSubject,SupervisorundExperimentanlegen. Diese haben jeweils einen Konstruktur (__init__()), um die Attribute zu setzen, die bisher im Dictionary gespeichert wurden. - Das
Subjectenthält zudem eine Methodeestimate_max_hr()basierend auf der Funktion. - Da wir nicht für jeden Testfall die Daten von Hand eingeben wollen, eine Kopie der
main.pynamenstest.pyanlegen (Beispiel, wie das aussehen könnte, finden Sie unten) - Geben Sie wieder den Link zum Repository in Sakai ab
Vorschlag für test.py
from my_classes import Subject, Supervisor, Experiment
if __name__ == "__main__":
# Erstellen eines Leistungstests
supervisor = Supervisor("FirstName", "LastName")
subject = Subject("FirstName", "LastName", "female", 30)
subject.estimate_max_hr()
experiment = Experiment("Leistungstest", "2021-01-01")
experiment.add_subject(subject)
experiment.add_supervisor(supervisor)
print(experiment)
Startpunkt für my_classes.py
class Subject():
def __init__(self, first_name, last, sex):
pass
def estimate_max_hr(self):
"""A function that estimates the maximum heart rate of a subject"""
pass
class Supervisor():
def __init__(self, first_name, last_name):
pass
class Experiment():
def __init__(self, name, date):
pass
def add_subject(self, subject):
self.subject = subject
def add_supervisor(self, supervisor):
pass