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() eller withdraw().
  • 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.

Inget konto är skapat än.

Programmering 2-koppling: direkt åtkomst till _balance undviks. I stället styr metoderna vilka ändringar som är tillåtna.

Öva: skapa egna inkapslade attribut

  1. Skapa en klass Student med namnet publikt och betyg som ett privat attribut _grade.
  2. Skriv en metod set_grade() som bara godkänner betyg mellan 0 och 100.
  3. Skriv en metod get_grade() som returnerar betyget.
  4. 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_ och set_ används för att hantera privata fält.
  • Inkapsling förbättrar säkerhet, läsbarhet och kodens hållbarhet.

Tillbaka till Kapitel 3