Programmering nivå 2
Kap 3.4 – Inkapsling och attribut
Skydda objektets data och styr åtkomst med metoder.
Mål med lektionen
När du har arbetat klart med denna lektion ska du:
- Förstå vad inkapsling innebär och varför det är viktigt.
- Känna till hur man markerar privata attribut i Python.
- Kunna använda metoder, getters och setters, för att kontrollera åtkomst till data.
Så här lär du dig bäst
Tänk på inkapsling som att bygga en maskin där vissa delar är synliga och andra dolda. Börja med exemplen och testa att göra attribut privata. Skapa egna metoder som kontrollerar hur data läses och skrivs. Jämför med hur du använt attribut direkt tidigare.
Centrala begrepp
- Inkapsling: att dölja objektets inre data och endast ge åtkomst via metoder.
- Publikt attribut: ett fält som kan nås direkt utifrån.
- Privat eller internt attribut: ett fält som är avsett att användas inuti klassen, ofta skrivet med ett inledande understreck.
- Läsa via metod: att hämta ett värde med en metod, till exempel
get_balance(). - Ändra via metod: att ändra ett värde med en metod som först kontrollerar om
ändringen är tillåten, till exempel
deposit()ellerwithdraw(). - Getter och setter: vanliga namn på metoder som läser eller ändrar privata fält.
Inkapsling är en grundsten i OOP eftersom det skyddar objektets inre tillstånd och minskar risken för fel. Det gör också din kod tydligare och mer kontrollerad.
Problemet: attribut kan ändras direkt
I tidigare kapitel har du ändrat attribut direkt, till exempel car1.year = 2023. Det kan
fungera i enkla exempel. Problemet är att ett attribut också kan få ett orimligt värde om inget
kontrollerar ändringen.
class BankAccount:
def __init__(self, owner, balance):
self.owner = owner
self.balance = balance
account = BankAccount("Emma", 1000)
print(account.balance)
account.balance = -999
print(account.balance)
Här kan saldot bli negativt direkt utifrån. Objektet får ingen chans att säga nej. Det är just detta inkapsling försöker lösa.
Lösningen: styr ändringar med metoder
I Python är inget egentligen helt privat, men det är praxis att markera ett internt attribut med ett
inledande understreck: _. Det betyder: använd inte detta direkt utifrån, utan gå via
klassens metoder.
class BankAccount:
def __init__(self, owner, balance):
# Publikt attribut: kan läsas direkt.
self.owner = owner
# Internt attribut: ska ändras via metoder.
self._balance = balance # privat attribut
def deposit(self, amount):
# Sätt bara in positiva belopp.
if amount > 0:
self._balance += amount
def withdraw(self, amount):
# Ta bara ut pengar om beloppet är positivt
# och det finns tillräckligt med pengar.
if 0 < amount <= self._balance:
self._balance -= amount
else:
print("Uttaget nekas. Du får inte övertrassera kontot.")
def get_balance(self):
# Läs saldot via en metod.
return self._balance
account = BankAccount("Emma", 1000)
print(account.get_balance())
account.deposit(500)
print(account.get_balance())
account.withdraw(200)
print(account.get_balance())
Här används metoderna deposit(), withdraw() och
get_balance() för att hantera saldot på ett kontrollerat sätt.
owner är publikt och kan läsas direkt. _balance är däremot markerat som
internt. Det går tekniskt att skriva account._balance i Python, men understrecket
betyder att annan kod inte ska använda attributet direkt.
En setter är användbar när du vill kontrollera ett nytt värde innan det sparas i objektet. Du kan till exempel stoppa negativa tal, för höga betyg eller andra ogiltiga värden innan de ändrar objektets tillstånd.
Enklare sagt: först lärde du dig att objekt kan ha attribut. Nu lär du dig att objekt också bör få bestämma hur attributen får ändras.
Utskrifterna visar hur saldot ändras steg för steg: först startvärdet, sedan efter insättning och sist efter uttag. Metoderna säkerställer att ogiltiga belopp inte ändrar saldot.
Interaktiv övning: inkapslat bankkonto
Välj account1 eller account2. Skapa kontot en gång och testa sedan att
sätta in pengar, ta ut pengar och läsa saldot med get_balance(). Varje konto har
sitt eget _balance.
Programmering 2-koppling: direkt åtkomst till
_balance undviks. I stället styr metoderna vilka ändringar som är tillåtna.
Öva: skapa egna inkapslade attribut
- Skapa en klass
Studentmed namnet publikt och betyg som ett privat attribut_grade. - Skriv en metod
set_grade()som bara godkänner betyg mellan 0 och 100. - Skriv en metod
get_grade()som returnerar betyget. - Testa att skapa en elev och ändra betyg med metoden.
När du har försökt själv kan du ladda ner ett lösningsförslag: kap3-4-student-losningsforslag.py
Sammanfattning
- Inkapsling handlar om att skydda data och endast ge åtkomst via metoder.
- Python använder understreck
_för att markera privata attribut. - Metoder som
get_ochset_används för att hantera privata fält. - Inkapsling förbättrar säkerhet, läsbarhet och kodens hållbarhet.