TigerJython4Kids
Robotique Robotik
oop

16. OBJEKTORIENTIERTE PROGRAMMIERUNG

 

 

DU LERNST HIER...

 

wie du mit dem Konzept der objektorientierten Programmierung (OOP) die Wirklichkeit einfach und anschaulich als Software modellieren kannst. Dabei werden die Eigenschaften und Fähigkeiten von realen Objekten als Variable und Funktionen einer bestimmten Klasse aufgefasst. (Man nennt solche Variablen auch Instanzvariablen und die Funktionen auch Methoden.)

 

 

MUSTERBEISPIELE

 

Die Klasse Snake ist bereits im Modul snake definiert und steht dir mit

from snake import Snake

zur Verfügung. Du erzeugst eine einzelne Schlange unter Verwendung der speziellen Methode Snake(), die ausnahmsweise grossgeschrieben ist (entspricht dem Klassennamen). Man nennt sie Konstruktor der Klasse, weil man bei ihrem Aufruf  ein Objekt (auch Instanz genannt) erzeugt (konstruiert). Der Konstruktor hat genau die gleichen optionalen Parameter wie makeSnake(), du kannst der Schlage also damit ihre "Anfangseigenschaften" geben, beispielsweise

roxy = Snake()
kitty = Snake(heading = 90, pos = (1, 6))
roby = Snake(headColor = (255, 255, 0), tailColor = (30, 30, 0))


In deinem Programm erzeugst du 4 Schlangenobjekte und bewegst sie auf Quadraten. Um in der Funktion step() die Methoden eines bestimmten Objekts (einer Instanz) aufzurufen, verwendest du den Punktoperator. Um die Animation zu beschleunigen, schaltest du das automatische Rendering mit enableRepaint(False) ab und renderst erst, nachdem alle Schlagen eine Quadratseite abgelaufen sind.

 


Programm:

# Snake16.py

from oxosnake import *

pythy1 = Snake(headColor = (255, 0, 0), tailColor = (120, 0, 0), 
               pos = (0, 5), size = 3, speed = 90)
pythy2 = Snake(headColor = (255, 255, 0), tailColor = (120, 120, 0), 
               pos = (2, 1), heading = 90, size = 3, speed = 90)
pythy3 = Snake(headColor = (0, 255, 0), tailColor = (0, 120, 0), 
               pos = (6, 3), heading = 180, size = 3, speed = 90)
pythy4 = Snake(headColor = (0, 0, 255), tailColor = (0, 0, 120), 
               pos = (4, 7), heading = 270, size = 3, speed = 90)

def step(snake):
    snake.forward(2)
    snake.right(45)
    
enableRepaint(False)
while True:
    step(pythy1)
    step(pythy2)
    step(pythy3)
    step(pythy4)
    repaint() 
► In Zwischenablage kopieren

Schalte durch Entfernen (Auskommentieren) der Zeile enableRepaint(False) das automatische Rendering wieder ein und gebe eine Erklärung für das Programmverhalten.

 

Klassenableitung

Durch die Definition von Klassen werden Eigenschaften und Fähigkeiten in einer Programmstruktur zusammengefasst. Man spricht dabei von einer Kapselung (Encapsulation). In der OOP kannst du aber auch durch Klassenableitung (Inheritance) bestehende Klassen erweitern und verändern. Damit ist es möglich, Eigenschaften und Fähigkeiten hinzuzubauen, ohne dass man den Code der bestehenden Klasse verändern muss.

Im vorhergehenden Programm sind ja fast alle Schlagen gleichartig und haben alle eine zusätzliche Funktion step(). Du definierst daher deine eigene Klasse PySnake, welche einen einfacheren Konstruktor und eine zusätzliche Methode step() enthält.

Die Klassendefinition wird mit dem neuen Schlüsselwort class eingeleitet, gefolgt vom Klassennamen PySnake. In einer runden Klammer gibst du die Klasse Snake an, von der die neue Klasse abgeleitet ist. PySnake "erbt" damit alle Eigenschaften und Fähigkeiten der Klasse Snake, was heisst, dass einem Objekt von PySnake automatisch auch alle Eigenschaften und Fähigkeiten von Snake zur Verfügung stehen. Man sagt anschaulich, dass eine PySnake auch eine Snake ist (in Analogie zum Tierreich eine Untergattung).

Der Konstruktor der Klasse PySnake muss in Python mit __init__() definiert werden. Eigentlich wäre die Bezeichnung PySnake() naheliegender, da ja der Konstruktor aufgerufen wird, wenn man mit pythy = PySnake() ein Objekt erzeugt. Sowohl der Konstruktor und alle Methoden der Klasse müssen einen zusätzlichen Parameter self haben, den man meist aber gar nicht braucht.

Im Konstruktor von PySnake() initialisierst du die Klasse Snake, aus der PySnake abgeleitet ist. (Man nennt Snake auch die Basisklasse oder Superklasse von PySnake.) Merke dir einfach, dass du zur Initialisierung Snake.__init__(self, ...) schreiben musst. Schliesslich folgt die Definition der Methode step() mit dem zusätzlichen Parameter self.

Im Hauptprogramm erzeugst du vier Objekte pythy1..pythy4 und und rufst in einer Endlosschleife ihre Methode step() auf.

 

Programm:

# Snake16a.py

from oxosnake import *

class PySnake(Snake):
    def __init__(self, color, position, direction):
        Snake.__init__(self, headColor = color,
                       tailColor = reduceBrightness(color, 2),
                       pos = position, size = 3,
                       heading = direction,
                       speed = 90)

    def step(self):
        self.forward(2)
        self.right(45)

pythy1 = PySnake(RED, (0, 5), 0)
pythy2 = PySnake(YELLOW, (2, 1), 90)
pythy3 = PySnake(GREEN, (6, 3), 180)
pythy4 = PySnake(BLUE, (4, 7), 270)

enableRepaint(False)
while True:
    pythy1.step()
    pythy2.step()
    pythy3.step()
    pythy4.step()
    repaint() 
► In Zwischenablage kopieren

Das Programm ist durch die Definition einer eigenen Klasse nicht nur eleganter geworden, sondern gibt dir die Möglichkeit, das neue Objekt PySnake wie ein durch das System vordefiniertes Objekt zu verwenden. Dazu fügst du die Klassendefinition in eine neue Datei mit dem Namen pysnake.py ein und lädst diese mit der Option Modul herunterladen auf die Oxocard.

Programm:

from oxosnake import *

class PySnake(Snake):
    def __init__(self, color, position, direction):
        Snake.__init__(self, headColor = color, 
                       tailColor = reduceBrightness(color, 10), 
                       pos = position, size = 3, 
                       heading = direction, 
                       speed = 90)
    
    def step(self):
        self.forward(2)
        self.right(45)
► In Zwischenablage kopieren

In irgendeinem Programm kannst du nun die neue PySnake verwenden, indem du das Modul pysnake importierst.

Programm:

from pysnake import *

pythy1 = PySnake(RED, (0, 5), 0)
pythy2 = PySnake(YELLOW, (2, 1), 90)
pythy3 = PySnake(GREEN, (6, 3), 180)
pythy4 = PySnake(BLUE, (4, 7), 270)

enableRepaint(False)
while True:
    pythy1.step()
    pythy2.step()
    pythy3.step()
    pythy4.step()
    repaint()         
► In Zwischenablage kopieren

Du hast jetzt dein erstes Bibliotheksmodul geschrieben und dabei eine weitere wichtige Strukturierungsmöglichkeit von Programmen kennen gelernt.

 

 

MERKE DIR...

 

Die OOP stellt dir ein Programmierkonzept zur Verfügung, mit dem du die Realität anschaulich und übersichtlich modellieren kannst. Dabei werden Eigenschaften und Fähigkeiten als Instanzvariable und Methoden in der Klassendefinition abgebildet. Man erzeugt ein Objekt einer Klasse durch Aufruf ihres Konstruktors und führt seine Methoden mit dem Punktoperator aus.

Klassen können verändert und ergänzt werden, indem man sie ableitet. Es entsteht dadurch eine ähnliche Abhängigkeit wie beispielsweise bei der Klassifikation im Tierreich.

 

 

ZUM SELBST LÖSEN

 

 

1a.

Bei jedem Klick auf einen von dir gewählten Button soll eine neue Schlage mit speed = 100 und der Länge 1 (nur der Kopf) mit zufälliger Farbe an zufälliger horizontaler Position auf der untersten Zeile entstehen. Du fügst sie in eine Liste family, die zuerst leer ist. In der Endlosschleife bewegst du alle Familienmitglieder nach oben, bis sie auf y = -1 sind und setzt sie dann wieder auf die unterste Zeile. Eine zufällige Farbe aus den 7 Grundfarben erhältst du mit getRandomColor(). Verwende enableRepaint(False), um die Animation zu beschleunigen.

 


1b.

Mache dasselbe mit Schlangen der Länge 2, welche ein Schwanzfarbe haben, die der um den Faktor 20 abgedunkelten Kopffarbe entspricht. Verwende dazu die Funktion reduce(color, 20), welche die abgedunkelte Farbe von color zurückgibt.

 

2.

Leite aus Snake eine Klasse DancingSnake ab, deren Konstruktor wie oben bei PySnake aufgebaut ist, aber nur die Anfangsposition der Schlage als Parameter verwendet. Die Schlangen haben alle speed = 100. Mit color = getRandomColor() erhält der Kopf jeder neuen Schlage eine Zufallsfarbe und mit reduce(color, 20) der zugehörige Schwanz die gleiche, aber dunklere Farbe. Die DancingSnake hat zudem eine Methode dance(),  mit der sie auf einem Achteck mit 1 Schritt Seitenlänge eine volle Runde dreht.

Erstelle 3 (oder mehr) Instanzen der DancingSnake an verschiedenen (eventuell zufälligen) Positionen und lasse sie endlos tanzen.