Begriff
Encapsulation (Kapselung)
Warum wichtig?
Dieser Begriff ist ein Knoten im SengakujiWorks-Wissensnetz. Nutze Level 0 für die erste Einordnung, Level 1 für Praxis, Level 2 für technische Struktur und Level 3 für Grenzen, Fallstricke und Expertenkontext.
Ein Auto hat einen Motor.
Aber du kannst während der Fahrt nicht die Zündkerzen anfassen.
Es gibt eine Motorhaube (Schutz).
Du darfst nur das Lenkrad und Pedale benutzen (Interface).
So ist es auch bei Objekten.
Du versteckst die komplizierten Innereien (private) und zeigst nach außen nur sichere Methoden (public).
Das verhindert, dass jemand aus Versehen motor.temperatur = 9999 setzt und alles explodiert.
Merksatz: Das Verbergen von Implementierungsdetails einer Klasse vor dem Zugriff von außen, um Datenintegrität zu schützen und Abhängigkeiten zu reduzieren.
Access Modifiers (Java/C++/TS):
- private: Nur ich (die Klasse) darf das sehen.
- protected: Ich und meine Kinder (Vererbung).
- public: Alle.
Python:
Hat kein echtes private.
Man nutzt Unterstrich _variable ("Bitte nicht anfassen") oder Doppel-Unterstrich __variable (Name Mangling, schwerer anzufassen).
1. Getter & Setter
Statt obj.name = "Max", mache obj.setName("Max").
Warum?
Im Setter kannst du prüfen: "Ist der Name leer? Ist er zu lang?"
Wenn du direkten Zugriff (public Name) erlaubst, verlierst du die Kontrolle.
Modern: Properties (C# / Python @property). Sieht aus wie eine Variable obj.name, ist aber insgeheim eine Funktion.
2. Information Hiding
Kapselung ist nicht nur "Variablen verstecken".
Es geht um "Design-Entscheidungen verstecken".
Wenn deine Klasse intern eine ArrayList nutzt, aber nach außen nur List interface zurückgibt, kannst du später auf LinkedList wechseln, ohne dass der Rest der App kaputt geht.
Du entkoppelst die Module.
3. Law of Demeter
"Rede nicht mit Fremden."
Schlecht: auto.getMotor().getZylinder().zünden(). (Du greifst tief in die Eingeweide).
Gut: auto.fahreLos().
Das Auto kümmert sich selbst um Motor und Zylinder. Das ist gute Kapselung.
1. Kapselung vs. Memory Layout (C++)
In High-Level Sprachen wie Java ist private eine strikte Compiler-Regel. Der Compiler wirft einen Error.
In C++ ist private im fertigen RAM beim Ausführen (Runtime) nur noch heiße Luft. Das Memory Layout (Struct) liegt flach im C-Adressraum.
Ein findiger Hacker nutzt Pointer Arithmetic:
ClassA obj; int* ptr = (int*)&obj; *(ptr + 1) = 999;
Mit diesem Code springt man skrupellos über den private-Zaun und überschreibt die geheime Memory-Adresse der internen Variable von außen. Kapselung ist nur ein "Sicherheitsgurt" beim Kompilieren, kein kryptografischer Schutz im echten Arbeitsspeicher!
2. Dependency Injection vs. Harte Kapselung
Manchmal ist absolute Kapselung toxisch für Unit Test.
Wenn eine Klasse Car intern fest im Code engine = new Engine() macht (perfekt versteckt!), kannst du das Auto schwer testen, weil immer der echte, teure V8-Motor hochfährt (der z.B. eine DB-verbindung braucht).
Lösung: Du öffnest die Kapselung leicht, per Konstruktor: public Car(Engine e). Das nennt sich Inversion of Control (IoC) / Dependency Injection. Dem Auto wird der Motor von außen (von einem Framework wie Spring) "injeziert". Für Tests kannst du dem Auto dann heimlich einen MockEngine (Dummy) unterschieben! Gute Kapselung verbirgt den State, aber nicht die Abhängigkeiten (Dependencies).
3. Das "Anemic Domain Model" (Anti-Pattern)
Oft siehst du Klassen, die nur aus 50 privaten Variablen und 50 primitiven get() / set() Methoden bestehen, aber keine eigene Logik (Business-Code) enthalten.
Diese Klassen sind "blutarm" (Anemic). Martin Fowler (Architektur-Guru) hasst das.
Das bricht das OOP-Kapselungs-Prinzip massiv, weil die "Intelligenz" nun in externen Services wohnt, welche die dummen Daten-Klassen nur wie Kisten durchwühlen, auspacken, rechnen und wieder einpacken.
Der Kern von echte OOP-Kapselung ist: Daten und die Logik, die auf diesen Daten operiert, zwingend in demselben Objekt verschmolzen zu halten (Rich Domain Model).
Quick-Check
Module Pattern (JS)?
In altem JS nutzte man Closures (function() { var privat = 1; return { public: 2 } }), um Kapselung zu erreichen. Heuteclassmit#privatFeldern.Reflection?
Mit Reflection (java.lang.reflect) kann manprivateVariablen trotzdem lesen und schreiben ("Hack"). Nützlich für Frameworks, gefährlich für App-Code.Immutable Objects?
Die ultimative Kapselung. Wenn ein Objekt nach Erstellung nie wieder geändert werden kann, ist es automatisch sicher (Thread Safe) und fehlerfrei.