- 1 Section
- 10 Lessons
- unbegrenzt
- Objektorientierte Programmierung (OOP)10
Kapselung und Zugriffsmodifikatoren
Kapselung ist die erste der vier Säulen der OOP (siehe L1) und vielleicht das wichtigste praktische Prinzip im Alltag. Die Idee: ein Objekt soll nicht alle seine Daten preisgeben. Manche Attribute sind interne Implementierungsdetails, die andere Klassen nichts angehen. Wer das ignoriert, baut Software die bei jeder Änderung an einer Stelle an zehn anderen kaputt geht.
Diese Lektion erklärt das Konzept der Sichtbarkeit (public/protected/private) in Java-Stil, vergleicht es mit Pythons Konvention, zeigt warum Kapselung wichtig ist, und führt Getter/Setter sowie Properties ein. Klausurfrage-Klassiker!
1) Das Konzept: Information Hiding
Stell dir eine Mikrowelle vor. Sie hat einen einfachen Bedienknopf außen – Zeit einstellen, Start drücken. Was passiert intern (Mikrowellen-Generator, Drehteller-Motor, Magnetron, …) verbirgt sich hinter dem Gehäuse. Du als Nutzer kümmerst dich nicht drum. Wenn der Hersteller das Magnetron-Modell wechselt, ändert sich für dich nichts – die Bedienung bleibt gleich.
Genauso bei Klassen: nach außen bietet das Objekt eine kleine, stabile Schnittstelle an (öffentliche Methoden). Intern versteckt es Details (private Attribute, Hilfsmethoden). Das nennt sich Information Hiding, und das aktive Versteckenstellen heißt Kapselung.
Vorteile:
- Wartbarkeit: interne Änderungen ohne Auswirkungen auf andere Klassen
- Sicherheit: falsche Werte gelangen nicht ins Objekt
- Klarheit: die öffentliche Schnittstelle ist klein und gut dokumentiert
- Refactoring: du kannst die interne Datenstruktur ändern
2) Die drei Sichtbarkeits-Zonen
Java, C# und ähnliche Sprachen kennen drei explizite Sichtbarkeitsstufen. Stell sie dir als konzentrische Schichten vor:
einzahlen(), abheben(), die man von außen aufruft.+ für public, # für protected, - für private. In Java schreibst du die Schlüsselwörter explizit. Faustregel: standardmäßig private, nur was wirklich von außen gebraucht wird auf public. protected sparsam und bewusst.3) Sichtbarkeits-Matrix
Schauen wir konkret, wer von wo aus zugreifen darf. Java kennt vier Stufen – die obige plus package-private (kein Modifier):
internal. C++ hat friend – andere Klassen explizit als „Freunde" erklären, die Zugriff bekommen.4) Java-Beispiel: kapseln eines Kontos
Konkret: ein Konto ohne Kapselung, gegenübergestellt mit einer gut gekapselten Version. Zuerst der naive Stil:
Das ist die Hölle. Jede Codestelle kann das Konto kaputt machen. Wenn morgen jemand behauptet „der Saldo war -7000 weil ein Buchungsfehler", weißt du nicht wo im Code das passiert ist. Die gute Variante:
Jetzt ist das Konto „sicher". Niemand kann den Saldo direkt manipulieren – nur über einzahlen() und (analog) abheben(), die Validierungen einbauen. Der Inhaber ist sogar final – nach dem Konstruktor unveränderbar.
5) Vor/Nach-Vergleich
- Jeder kann saldo direkt setzen
- Keine Validierung möglich
- Negative Beträge, NULL-Werte, falsche Formate – alles geht durch
- Refactoring (z.B. saldo zu Cent statt Euro umstellen) zerstört Code
- Bugs schwer zu finden – Saldo kann von überall geändert werden
- Sicherheitsrisiko bei sensiblen Daten
- Änderungen nur durch validierte Methoden
- Negative Beträge können abgelehnt werden
- Interne Implementierung kann geändert werden
- Bugs leicht zu finden – nur eine Stelle pro Operation
- Sensible Daten geschützt
- Schnittstelle stabil, auch wenn intern alles umgebaut wird
6) Getter und Setter
Ein Getter ist eine Methode, die einen Attribut-Wert zurückgibt. Ein Setter setzt einen Wert mit optionaler Validierung. Klassisches Konvention in Java:
Für boolean-Werte heißt der Getter üblicherweise isXxx() statt getXxx() – also isAktiv(), isVolljaehrig().
Eine kontroverse Diskussion: brauchst du wirklich für jedes Attribut Getter und Setter? Wenn dein Setter nur stumpf zuweist (ohne Validierung), warum dann nicht direkt public machen? Argument: spätere Validierung lässt sich einfach einbauen ohne andere Klassen anzupassen. Gegenargument: kostet Code, lenkt vom Wesentlichen ab. Praxis: Getter immer, Setter nur wenn nötig – viele Attribute sollten nach dem Konstruktor unveränderlich sein (immutable).
7) Pythons Konvention
Python hat keine echten Zugriffsmodifikatoren. Alles ist technisch public. Stattdessen gibt es Konventionen mit Unterstrichen:
| Konvention | Bedeutung | Technisch |
|---|---|---|
name | public, frei zugänglich | von überall lesbar/schreibbar |
_name | protected, „bitte nicht anfassen" | technisch lesbar, aber Konvention sagt: lass es bleiben |
__name | private (Name-Mangling) | wird intern zu _Klasse__name umbenannt – Zugriff erschwert, nicht unmöglich |
Pythons Philosophie: „We are all consenting adults here". Wer trotz Unterstrich auf ein Attribut zugreift, weiß was er tut. Funktioniert in der Praxis erstaunlich gut. Java-Profis empfinden das oft als gefährlich – Python-Profis als befreiend.
8) Python-Properties
Wenn du in Python doch Validierung beim Setzen brauchst, nutzt du @property – elegante Lösung ohne Verbose-Code:
Das Beste daran: du behältst die schöne Attribut-Syntax p.alter statt p.getAlter() – aber bekommst Validierung trotzdem. Java-Entwickler beneiden Python um das.
9) Praktische Empfehlungen
Wie sollst du das in deinen eigenen Klassen anwenden? Faustregeln aus der Praxis:
- Default-Sichtbarkeit: private. Erst öffnen, wenn nötig.
- Attribute selten public. Stattdessen Getter, oder eine sinnvolle Methode wie
get_volljaehrig(). - Setter nur wenn nötig. Viele Klassen sind immutable – nach Konstruktor unveränderlich.
- Validierung in Settern und Konstruktoren. Lieber früh fehlschlagen als spät falsche Werte verarbeiten.
- Helper-Methoden private. Wenn eine Methode nur intern gebraucht wird, dann mit
privatebzw._markieren. - Konsistenz: in einem Projekt einheitlich entscheiden, ob bool-Getter
isAktiv()odergetAktiv()heißt. - Records / Data Classes: für reine Datencontainer (Point, Coordinate) sind moderne Sprachen optimiert – Java
record, Python@dataclass, Kotlindata class.
10) Häufige Fragestellungen in Prüfungen
Klausur-Klassiker zum Thema Kapselung:
- „Definiere Kapselung." → Bündelung von Daten und Methoden + Verstecken interner Details
- „Warum sollte ein Attribut privat sein?" → Validierung, Wartbarkeit, Stabilität der Schnittstelle
- „Was bedeutet protected?" → zugreifbar von eigener Klasse + Unterklassen (siehe L5)
- „Was sind Getter und Setter?" → öffentliche Methoden zum geregelten Zugriff auf private Attribute
- „Welche Sichtbarkeit hat ein Java-Attribut ohne Modifier?" → package-private
- „Beispiel für Kapselungsverletzung?" → öffentliche Felder, kein-validierende Setter, gibt Referenzen auf interne Collections raus
- „Was ist Information Hiding?" → Konzept, dass Implementierungsdetails nicht nach außen sichtbar sein sollten
Zusammenfassung
Kapselung = Daten + Methoden bündeln und interne Details vor außen verbergen. Drei Sichtbarkeitsstufen in Java/C#: public (überall), protected (Klasse + Unterklassen), private (nur eigene Klasse). UML-Symbole: +, #, -. Getter/Setter als geregelter Zugriff – Setter mit Validierung. Python hat keine echten Modifikatoren, nutzt Unterstrich-Konventionen: _name protected, __name private mit Name-Mangling. Python-Properties mit @property ersetzen Java-Getter/Setter elegant. Faustregel: Standard private, nur was wirklich nach außen muss public.
