← CS Lab Programming Foundations / Python OOP
Python OOP — card 1 of 4
Python OOP — card 2 of 4
Python OOP — card 3 of 4
Python OOP — card 4 of 4

Object-oriented programming bundles data and the functions that act on it into one thing — an object. A class is the blueprint; an object is one concrete thing built from it. The carousel showed the shape; here is the machinery underneath.

Where you meet it

What it does

It keeps related state (attributes) and behaviour (methods) together, so you reason about one well-defined unit instead of loose variables scattered across your code. Each object carries its own data; the class defines what they all can do.

Reach for a class when data and behaviour genuinely belong together — not before.

How it works

A class is a factory. Calling it runs __init__ — the initialiser — once, to set up the new object's attributes. self is the object being built or used: it is how an instance refers to itself, and Python passes it in automatically.

class Dog:
    species = "Canis familiaris"      # class attribute — shared by all dogs

    def __init__(self, name, age):    # runs when you build one
        self.name = name              # instance attribute — unique per dog
        self.age = age

    def speak(self):                  # a method: self is the caller
        return f"{self.name} says woof"

rex = Dog("Rex", 3)                   # builds an instance
rex.speak()                           # "Rex says woof"

class Puppy(Dog):                     # inheritance: Puppy is-a Dog
    def speak(self):
        return f"{self.name} yips"    # overrides the parent method

Puppy gets everything from Dog for free and only changes what differs. That is reuse without copy-paste.

Watch out

  • Don't forget self. Every method's first parameter is the instance; def speak(): without it raises a TypeError the moment you call it.
  • Mutable class attributes are shared. Writing tricks = [] at class level means one list for every instance — append to it through one dog and every dog "learns" the trick. Put per-object data in __init__ with self.tricks = [].
  • is-a vs has-a. Inheritance models "a Puppy is a Dog". If the relationship is "a Car has an Engine", use composition (store it as an attribute) instead of inheriting.
  • Not everything needs a class. A plain function, a dict, or a dataclass is often clearer. Reach for a class when data and behaviour genuinely belong together.

Go deeper

Objektorientierte Programmierung bündelt Daten und die Funktionen, die auf ihnen arbeiten, in einem Ding — einem Objekt. Eine Klasse ist der Bauplan; ein Objekt ein konkretes Exemplar daraus. Das Karussell zeigte die Form; hier ist die Mechanik darunter.

Wo es vorkommt

Was es tut

Es hält zusammengehörigen Zustand (Attribute) und Verhalten (Methoden) beisammen, sodass du über eine klar umrissene Einheit nachdenkst statt über lose Variablen quer im Code. Jedes Objekt trägt seine eigenen Daten; die Klasse legt fest, was sie alle können.

Greif zur Klasse, wenn Daten und Verhalten wirklich zusammengehören — nicht früher.

Wie es funktioniert

Eine Klasse ist eine Fabrik. Der Aufruf führt einmalig __init__ aus — den Initialisierer —, um die Attribute des neuen Objekts zu setzen. self ist das gerade gebaute oder benutzte Objekt: so referenziert sich eine Instanz selbst, und Python übergibt es automatisch.

class Dog:
    species = "Canis familiaris"      # Klassenattribut — von allen geteilt

    def __init__(self, name, age):    # läuft beim Bauen
        self.name = name              # Instanzattribut — je Hund eigen
        self.age = age

    def speak(self):                  # Methode: self ist der Aufrufer
        return f"{self.name} says woof"

rex = Dog("Rex", 3)                   # baut eine Instanz
rex.speak()                           # "Rex says woof"

class Puppy(Dog):                     # Vererbung: Puppy is-a Dog
    def speak(self):
        return f"{self.name} yips"    # überschreibt die Elternmethode

Puppy erbt alles von Dog und ändert nur, was abweicht. Das ist Wiederverwendung ohne Copy-Paste.

Worauf achten

  • self nicht vergessen. Der erste Parameter jeder Methode ist die Instanz; def speak(): ohne ihn wirft beim Aufruf sofort einen TypeError.
  • Mutable Klassenattribute werden geteilt. tricks = [] auf Klassenebene heißt: eine Liste für alle Instanzen — fügst du über einen Hund hinzu, "lernt" jeder Hund den Trick. Objekteigene Daten gehören in __init__ mit self.tricks = [].
  • is-a vs has-a. Vererbung modelliert "ein Puppy ist ein Dog". Lautet die Beziehung "ein Car hat einen Engine", nimm Komposition (als Attribut speichern) statt zu erben.
  • Nicht alles muss eine Klasse sein. Eine schlichte Funktion, ein dict oder eine dataclass ist oft klarer. Eine Klasse lohnt sich, wenn Daten und Verhalten wirklich zusammengehören.

Mehr dazu

Next up
Programming FoundationsPython Error Handling Programming FoundationsPython Environments & Packaging All concepts →