Es existieren unterschiedliche Ansätze, Software zu entwickeln. Dabei werden verschiedene Programmierparadigmen unterschieden.
Ein Paradigma (Plural Paradigmen) ist eine grundsätzliche Denkweise.
Übersetzt aus dem griechischen bedeutet es „Beispiel, Vorbild, Muster“ oder „Abgrenzung, Erklärungsmodell, Vorurteil“; auch „Weltsicht“ oder „Weltanschauung“.
Quelle: https://de.wikipedia.org/wiki/Paradigma
Um die Sinnhaftigkeit "moderner" Programmierparadigmen zu verstehen, hilft ein Einblick in die historische Art zu programmieren und die dabei entstehenden Probleme. Die ersten Programmiersprachen waren hardwarenah. Ein Prozessor hat einen Befehlssatz. Die darin enthalten Befehle stehen im Speicher (Register) und werden nacheinander sequentiell abgearbeitet. Eingaben, Zwischenergebnisse und Ergebnisse werden ebenfalls in Registern gespeichert.
Aufgabe:
Analysiert folgende Beispiele für Assemblercode und notiert Probleme dieser Art zu programmieren:
https://inf-schule.de/deklarativ/fp_python/warumfunktional/einstieg_spaghetticode
https://inf-schule.de/deklarativ/fp_python/warumfunktional/exkurs_strukturierteprogrammierung
Weitere Übungen zu Assembler werden im Lehrbereich technische Informatik durchgeführt: https://wiki-lk.gts-leipzig.de/Technische_Informatik
Programmiersprachen folgen mindestens einem, häufig mehreren Paradigmen. Im Folgenden werden wir folgende Paradigmen betrachten.
Quelle: https://link.springer.com/referenceworkentry/10.1007/978-3-662-57492-8_68-1
imperativ
im Vordergrund steht Lösungsweg (wie). Nutzt Grund-Kontrollstukturen: Sequenz von Anweisungen (Nacheinanderausführung), Schleife/Wiederholung und Verzweigung/Bedingung.
nicht imperativ
im Vordergrund steht das Problem (was)
prozedur-orientiert | objekt-orientiert (OOP) | funktional | deklarativ | |
---|---|---|---|---|
Konzept | Algorithmus in überschaubare Teile (Unterprogramme, Prozeduren, Funktionen) zerlegt Parameterübergeben und Ergebnisszurückgabe lokale und globale Variablen |
Modellierung durch Klassen/Objekte Objekte vereinen Daten (Attribute) und Verhalten (Methoden) Programm ist Interaktion zwischen Objekten |
Verkettung von Funktionen keine Variablen -> keine Seiteneffekte |
Beschreibung des Problems / nicht des Ablaufs |
Sprachen | Python, C, Java | Java, C++, Python | Haskell, Lisp, Scala, Python | SQL, Prolog |
Im Folgenden werden wir genau auf einzelne Paradigmen eingehen.
Fokus auf Modellierung der realen bzw. gedachten Welt (in abstrakter Form, entsprechend reduziert).
Aufgabe:
Seht euch folgende Videos an und notiert Kernkonzepte der Objektorientierung.
https://www.youtube.com/watch?v=ws_KI4Wun4I (Sichtbarkeit package und abstract kann ignoriert werden)
https://www.youtube.com/watch?v=2le2YYr3N7s
https://www.youtube.com/watch?v=w5M1IlvILLg
Objekte bestehen aus Attributen, Attributwerten und Methoden. Sie stellen meist Gegenstände dar, denen charakteristische Eigenschaften und ein bestimmtes Verhalten zugeordnet wird. Objekte können als Objektkarten dargestellt werden.
Eine beispielhafte Objektkarte für das Objekt mit dem Namen "Peter" der Klasse (wir sehen gleich, was das ist) MENSCH.
Eine Klasse ist ein Bauplan für Objekte. Sie definiert Attribute und Methoden (aber keine Attributwerte!). Von eine Klasse können beliebig viele Objekte (Instanzen) erzeugt werden.
Klassen und Objekte können in der Sprache UML mit Klassendiagrammen modelliert werden.
Aufgabe
Seht euch zur Modellierung in UML folgende Videos an und notierte wichtige Konzepte:
https://www.youtube.com/watch?v=2hZmqX60tLg (# (protected) kann ignoriert werden)
https://www.youtube.com/watch?v=5baxIRQJ1FM
Klassen werden mit Klassenkarten modelliert. Beispielhaft für die Klasse Mensch aus dem obigen Beispiel.
Mensch |
---|
+ name: str - alter: int + größe: int - gewicht: int + haarfarbe: str + haarlänge: str + augenfarbe: str |
+ Mensch(name:str, alter:int, größe:int, ...):Mensch # Konstruktor + get_alter():int + get_gewicht():int + set_gewicht(gewicht:int):void |
Allgemein:
Klassenname |
---|
sichtbarkeit (+=public, -=private) attributename: datentyp ... ... |
sichtbarkeit methodenname(parametername,parametertyp, ...):Rückgabetyp ... ... |
Wie in der echten Welt stehen Objekte miteinander in Beziehung. Dies ist notwendig, damit sie miteinander interagieren/kommunizieren können. Beispiel: Die Klasse Fahrer muss die Klasse Auto kennen um sie steuern zu können.
Dabei werden folgenden Beziehungen voneinander unterschieden.
Die Zahlen an den Beziehungen stellen Multiplizitäten an
Vererbung ist eine spezielle Form der Beziehung. Dabei übernehmen Kindklassen Attribute und Methoden der Elternklassen und erweitern/modifizieren diese.
Hier eine vereinfachte Abbildung ohne Sichtbarkeiten und Typen.
= Vielgestaltigkeit (Griechisch)
Die Polymorphie der objektorientierten Programmierung ist eine Eigenschaft, die in Zusammenhang mit Vererbung einhergeht. Eine Methode ist genau dann polymorph, wenn sie von verschiedenen Klassen unterschiedlich genutzt wird. (Quelle https://www.roberta-home.de/fileadmin/user_upload/WebBooks/JavaBand/RobertaBuchch7.html)
Beispiel:
Ihr kennt bereits die Methode len(...). Diese funktioniert seltsamerweise für Strings, Listen und andere Klassen. Der Grund dafür ist, dass diese Methode polymorph ist. Sie wird in einer Elternklasse definiert, von der sowohl die Klassen str und list erben. Jede der genannten Klassen stellte eine eigene Implementierung für len(...) bereit. (Hinweis: len(...) ruft len()_ der Klasse auf, eine komische Python Besonderheit.)
(für Interessierte ein genauerer Einblick in Pythons Typsystem: https://miro.medium.com/v2/resize:fit:2000/format:webp/1*TTKjn3Ejq5Zc0LhtNre2pQ.png).
Objekte sollten nur Zugriff auf "nötigste" zulassen. Im Beispiel der Klasse Mensch von oben soll niemand auf Gewicht eines Menschen zugreifen dürfen (Datenschutz).
Kapselung kontrolliert Zugriff auf Methoden bzw. Attribute von Klassen. Der Zugriff "von außen" kann verhindert werden (private, UML-Symbol "-"), nur für abgeleitete Klassen erlaubt (protected "#") oder für alle erlaubt (public, UML-Symbol "+")
Objekte kommunizieren mit Botschaften untereinander. Eine Botschaft ist hierbei der Aufruf einer Methode eines anderen Objekts mit den benötigten Argumenten. Als Beispiel stellt ein Schüler-Objekt dem Lehrer-Objekt "tempel" eine Frage: tempel.fragen("wofür brauchen wir das alles?")
Aufgaben
https://info-wsf.de/uebungsaufgaben-klassenbeziehungen/ (Python nutzt def ´__str__(self)´ statt toString wie Java)
https://inf-schule.de/oop/python
UML-Diagramme können mit Draw.io (siehe Softwareliste Abitur) erstellt werden.
Aufgabe:
Erklären Sie, welche Probleme "klassischer" Programmierung das funktionale Paradigma lösen will.
Beschreiben Sie das funktionale Paradigma.
Erläutern Sie, wie das funktionale Paradigma in Python umgesetzt werden kann.
Nutzen sie unter anderem https://de.wikipedia.org/wiki/Funktionale_Programmierung
Imperative Programmierung bringt viele Probleme mit sich:
Lösung durch funktionale Programmierung
Beispiel Seiteneffekte der Sortierung
Iterativ | funktional |
---|---|
list = [4,1,7,2,9] list.sort() print(list) |
list = [4,1,7,2,9] print(sorted(list)) print(list) |
Beispiel Higher-order function
def greet(func):
return func("World")
def hello(name):
return f"Hello, {name}"
print(greet(hello))
Profi-Zeug:
Funktionale Programmierung nutzt Rekursion für Wiederholung.
Iteration | Rekursion |
---|---|
Zugriff auf eine Datenstruktur erfolgt Schritt für Schritt (gleichartig wiederholend) | Wiederholung durch rekursive Selbstaufrufe einer Funktion (lat. recurrere = zurücklaufen) |
![]() |
![]() |
Rekursion: Abstieg und Aufstieg
Beides sind Formen der Wiederholung von Teilen eines Algorithmus.
|Iteration|Rekursion|
|---|
|Wiederholung durch Aneinanderreihung|Wiederholung durch Ineinanderschachtelung|
|Schleifen|Selbstaufruf|
|Effizient (Zeit und Platz)|Elegante Problemlösung|
|Komplexerer Code mit Manipulation von Variablen|Hohe Beanspruchung des Stack (spezieller Bereich des Arbeitsspeichers), da die Parameter für jeden Aufruf extra gespeichert werden|
Im Unterricht behandelte Beispiel Fakultät, Fibonacci. ToDo: Wikieintrag erzeugen.