Czym jest enkapsulacja?
W programowaniu obiektowym enkapsulacja (hermetyzacja) to trzymanie danych obiektu i metod, które na nich działają, razem w jednej jednostce, zwykle klasie, oraz ukrywanie szczegółów wewnętrznych, tak aby inny kod mógł korzystać z obiektu tylko przez jego publiczne metody.
Aktualizacja: 24 września 2026
Załóżmy, że aplikacja bankowa przechowuje saldo każdego konta w zwykłej zmiennej. Dowolna linia w dowolnym miejscu programu może napisać account.balance = -500 i nic jej nie zatrzyma. Gdy na produkcji pojawi się ujemne saldo, musisz przeszukać cały kod w poszukiwaniu każdego miejsca, które go dotykało. Enkapsulacja to naprawia: saldo może się zmienić tylko przez kilka metod, a te metody pilnują reguł, na przykład tego, że wypłata nigdy nie może przekroczyć salda.
Jak działa enkapsulacja
Enkapsulacja łączy dwie idee:
- Grupowanie. Dane (saldo) i kod, który na nich działa (wpłata, wypłata), mieszkają w tej samej klasie.
- Ukrywanie. Inny kod widzi tylko publiczny interfejs klasy. Dane za nim są wewnętrzne, więc mogą się zmieniać tylko w sposób, na który pozwala klasa.
Reguła, której pilnuje klasa, nazywa się niezmiennikiem: tutaj "saldo nigdy nie jest ujemne". Ponieważ każda zmiana przechodzi przez metody klasy, niezmiennik obowiązuje bez względu na to, co robi reszta programu.
70
refused: not enough money
Kod z zewnątrz może odczytać acct.balance, ale właściwość nie ma settera, więc acct.balance = 1000 rzuca AttributeError. Jeśli saldo kiedykolwiek będzie złe, do sprawdzenia są dokładnie dwie metody.
Enkapsulacja w Pythonie
Python nie ma słowa kluczowego private. Opiera się na konwencjach nazewnictwa, które zna każdy programista Pythona:
name: publiczne, część interfejsu._name: wewnętrzne. Nic nie przeszkadza w odczycie, ale podkreślnik na początku mówi "nie polegaj na tym".__name: Python zmienia tę nazwę wewnątrz klasy (name mangling), żeby podklasa nie nadpisała jej przez przypadek.@property: zamienia metodę w coś, co odczytuje się jak atrybut, dzięki czemu można później dodać sprawdzenia bez zmiany kodu, który z niej korzysta.
0
False
42
Name mangling zapobiega pomyłkom, a nie dostępowi: zmieniona nazwa nadal działa. Python ufa, że programiści uszanują podkreślnik. W praktyce większość kodu w Pythonie używa jednego podkreślnika i @property, a podwójne podkreślniki zostawia dla klas, które mają być dziedziczone. Więcej o pisaniu klas znajdziesz w dokumentacji klas w Pythonie.
Enkapsulacja w Javie, C++ i JavaScripcie
Inne języki wymuszają ukrywanie. W Javie pole private może być używane tylko wewnątrz własnej klasy:
public class BankAccount {
private int balance; // hidden from every other class
public int getBalance() { return balance; }
public void withdraw(int amount) {
if (amount > balance) throw new IllegalArgumentException("not enough money");
balance -= amount;
}
}
Napisanie account.balance = 1000; w innej klasie się nie skompiluje: javac zgłasza balance has private access in BankAccount.
| Język | Ukryta składowa | Publiczna składowa | Kto wymusza |
|---|---|---|---|
| Python | _name, __name | name | Konwencja |
| Java | private int name | public int name | Kompilator |
| C++ | sekcja private: | sekcja public: | Kompilator |
| JavaScript | #name | name | Silnik JavaScriptu |
C++ domyślnie czyni składowe class prywatnymi, a składowe struct publicznymi. Prywatnych pól # w JavaScripcie, dodanych w ES2022, w ogóle nie da się odczytać spoza klasy. Dokumentacja omawia każdy przypadek: modyfikatory dostępu w Javie, specyfikatory dostępu w C++ i pola prywatne w JavaScripcie.
Dlaczego enkapsulacja jest ważna
- Reguły są w jednym miejscu. Sprawdzenie "żadnej wypłaty powyżej salda" jest zapisane raz, w
withdraw, a nie przed każdą wypłatą w programie. - Możesz swobodnie zmieniać wnętrze. Jeśli zdecydujesz się przechowywać pieniądze w całych groszach zamiast w liczbie float, zmieni się tylko klasa. Kod, który wywołuje
deposit(100), dalej działa. - Łatwiejsze debugowanie. Gdy wartość jest zła, podejrzanymi są nieliczne metody, które mogą ją zmieniać, a nie każda linia programu.
- Mniej do nauki i testowania. Klasę z trzema publicznymi metodami można zrozumieć i przetestować przez te trzy metody.
Enkapsulacja działa też powyżej poziomu klas. Moduł, który udostępnia dwie funkcje, a dziesięć pomocniczych trzyma wewnętrznie, jest enkapsulowany w ten sam sposób, podobnie jak system operacyjny, który pozwala programom otwierać pliki tylko przez wywołania systemowe.
Enkapsulację często myli się z abstrakcją. Abstrakcja decyduje, co oferuje interfejs; enkapsulacja chroni dane za nim. Strona o abstrakcji zawiera pełne porównanie obu pojęć. Razem z polimorfizmem i dziedziczeniem tworzą cztery filary programowania obiektowego.
Częste błędy
- Getter i setter dla każdego pola.
setBalance, który przyjmuje dowolną liczbę, niczego nie chroni. Udostępniaj operacje, których obiekt potrzebuje (withdraw), a nie surowy dostęp do każdego pola. - Zwracanie wewnętrznych obiektów. Metoda, która zwraca
self._items, daje wywołującemu prawdziwą listę, którą może teraz zmieniać. Zamiast tego zwróć kopię albo krotkę. - Traktowanie prywatności jak zabezpieczenia. Modyfikatory dostępu zapobiegają pomyłkom, a nie atakom. Kod w Javie może odczytać pola prywatne przez refleksję, a kod w Pythonie może bezpośrednio odczytać
_name. Hasła i klucze wymagają prawdziwej ochrony, takiej jak haszowanie i szyfrowanie.
Co dalej
Przeczytaj teraz o abstrakcji, gdzie wyjaśniona jest różnica między obiema ideami, a potem o polimorfizmie. Kurs Python krok po kroku buduje klasy, a kurs Java pokazuje enkapsulację wymuszaną przez kompilator.
Najczęściej zadawane pytania
Czym jest enkapsulacja w prostych słowach?
deposit i withdraw, które najpierw sprawdzają reguły. Nazwa pochodzi od kapsuły, czyli osłonki, która trzyma zawartość w środku.Jakie są przykłady enkapsulacji?
deposit i withdraw. Innym jest wbudowana w Pythona list: wywołujesz append i nigdy nie zarządzasz pamięcią, w której leżą elementy. Moduł, który udostępnia kilka funkcji, a swoje funkcje pomocnicze trzyma jako prywatne, to enkapsulacja na większą skalę.Jakie są trzy rodzaje enkapsulacji?
Czym jest enkapsulacja w C++ i jak się jej używa?
private i udostępniasz funkcje składowe public, które je odczytują albo zmieniają. Składowe class są domyślnie prywatne, a składowe struct domyślnie publiczne. Kompilator odrzuca każdy kod spoza klasy, który próbuje użyć prywatnej składowej.