In diesem Forum legt man großen Wert darauf, dass der Fragesteller "nachweist", dass er sich intensiv mit dem Thema beschäftigt hat. Eine Frage so zu nehmen, wie sie ist, fällt schwer. Ich kenne das aus meinen aktiveren Forumzeiten (damals mit Delphi) etwas anders. Dort hat man unterstellt, dass der Fragesteller wusste, was er tat. Erst, wenn er nachhaltig Unfug gemacht hat, wurde er weiterverwiesen. Hier wird eher unterstellt, dass er grundsätzlich erst mal keine Ahnung hat. Mag an der Programmiersprache python liegen, die m.E. einfach aussieht und kompliziert ist. Schon die Änderungen weniger Zeichen verändern die Wirkungsweise von Dingen ganz erheblich.
Aber ich möchte mich hier eben nicht an der Grundsatzdiskussion beteiligen.
Kürzeste Antwort:
Wenn Du Dich mit Objektorientierung beschäftigst und den Unterschied zwischen Klasse vs. Instanz bzw. Klassenvariable (bzw. Klassenfunktion) vs. Membervariable (bzw. Memberfunktion) verstehst, dann wird Dir das klar.
Etwas längere Antwort:
- Eine Klassenvariable gibt es nur genau einmal pro Klasse, selbst, wenn da kein einziger Member existiert.
- Eine Membervariable existiert für jede einzelne Instanz. Unterschiedliche Instanzen der selben Klasse können unterschiedliche Werte haben
Daraus abgeleitet das selbe für Funktionen:
Wenn eine Funktion auf Member- Variablen zugreift, dann kann das nicht als Klassenfunktion implementiert werden. Sie wüsste ja nicht, wo sie hingreifen soll. Es kann sein, dass es keinen oder mehrere Member gibt.
Nicht unerwähnt bleiben soll an dieser Stelle, dass es natürlich auch lokale/globale Variablen/Funktionen gibt.
Zwischen diesen Konzepten gilt es, vernünftig zu wählen.
Längste Anwort für heute:
Da Du nach Klassen/Instanzen gefragt hast, werde ich mal den Teil lokal/global nicht weiter auswalzen.
Als Klassenvariable könnte beispielsweise ein Instanz- Zähler dienen. Sobald eine Instanz der Klasse erzeugt wurde, muss dieser Zähler hochgezählt werden, wenn ein Objekt verschwindet, dann wieder heruntergezählt. (In Python ist letzteres nicht so ohne weiteres möglich, aber vom Konzept wäre es so). Man könnte auch in einer Klassenvariable irgendeinen Wert speichern, der definitiv für die gesamte Laufzeit des Programms gilt, aber umständlich beschafft werden muss (Anmeldedaten vielleicht).
Als Klassenfunktion werden typischerweise Funktionen verwendet, die irgendwas machen, was für ALLE Member der Klasse gilt (bzw. gelten würde).
Bei Klassenfunktionen/Klassenvariablen ist die Grenze zu (modul-)globalen Funktionen/Variablen fließend. Wenn sie mit der Klasse zu tun haben, dann sollten sie m.E. aus Gründen der Ordnung als Klassenfunktionen ausgebildet werden.
Als Membervariable dient eine Variable, wenn sie den Zustand eines Members beschreibt. Ein Instanz- Zähler wäre logischerweise bedeutungslos für den Zustand des Members selbst. Wenn das Objekt aber beispielsweise Fahrzeuge abbilden soll, dann muss schon jedes Fahrzeug sein eigenes Nummernschild kennen. Gleiches gilt dann für die Member- Funktionen. Wenn beispielsweise das Kennzeichen und das Baujahr als Zeichenkette ausgegeben werden soll, dann kann das nur eine Memberfunktion sein.
Einiges von dem, was ich gesagt habe, kann man natürlich auch anders erklären.
Ich versuche es auch mal abstrakt mit Pseudocode:
Code: Alles auswählen
class A:
#Klassenvariable
kv_letze_instanz : int = 0
#Klassenfunktion
def kf_baue_instanzen(anzahl_instanzen : int, init__wert : str):
result = []
for i in range(anzahl_instanzen):
#Zugriff auf Klassenvariable
A.kv_letze_instanz += 1
instanz = A(id = A.kv_letze_instanz, dummy = init__wert)
result.append(instanz)
return result
#Initialiserungsfunktion, diese wird immer implizit aufgerufen, wenn ein Objekt gebaut wird
#der erste Parameter "self" steht für die Instanz/Member
def __init__(self, id ; int, dummy : str):
self.id, self.dummy = id, dummy
#weitere Member- Funktion, hier wird auch auf die Klassenvariable zugegriffen
def mach_was(self, irgendwas : str):
self.dummy = irgendwas + self.dummy + ' LI:' +str (A.kv_letze_instanz)
#Benutzung der Klassen- Funktion
elemente = A.kf_baue_instanzen(5, 'X')
#Benutzung der Member- Objekte
for e in elemente:
#Benutzung der Memberfunktionen
e.mach_was('B->')
print (f"ID {e.id} DUMMY {e.dummy}")
Das Ergebnis sieht dann wie folgt aus:
Code: Alles auswählen
ID 1 DUMMY B->X LI:5
ID 2 DUMMY B->X LI:5
ID 3 DUMMY B->X LI:5
ID 4 DUMMY B->X LI:5
ID 5 DUMMY B->X LI:5
Grundsätzlich würde ich vereinfachend folgendes postulieren: Nahezu IMMER willst Du Membervariablen und Memberfunktionen benutzen. Wenn Du Klassenvariablen und Klassenfunktionen benutzen willst, dann ist das etwas Besonderes.