Definere klasser, opprette objekter og bruke metoder.
Klassar og objekt
No er det tid for å gå frå teori til praksis! I dette kapittelet skal du lære å definere dine eigne klassar i Python, og forstå korleis klassar og objekt heng saman.
Tenk på ein klasse som ei oppskrift eller ein mal. Dersom klassen er oppskrifta på ei kake, er objektet den ferdige kaka. Du kan bake mange kaker frå same oppskrift – kvar kake er eit unikt objekt, men alle følgjer same mal.
- Klasse: Ein mal eller blueprint som definerer kva attributtar (data) og metodar (funksjonar) objekt av denne typen skal ha
- Objekt: Ein konkret instans av ein klasse, med sine eigne verdiar for attributtane
- Instans: Eit anna ord for objekt – vi seier at vi "instansierer" ein klasse når vi lagar eit objekt av han
Lat oss lage ein enkel klasse som representerer ein person:
class Person:
def __init__(self, navn, alder):
self.navn = navn
self.alder = alder
def hilse(self):
print(f"Hei, jeg heter {self.navn} og er {self.alder} år gammel.")
# Lag objekter (instanser) av Person-klassen
person1 = Person("Kari", 25)
person2 = Person("Ola", 30)
# Bruk objektene
person1.hilse() # Hei, jeg heter Kari og er 25 år gammel.
person2.hilse() # Hei, jeg heter Ola og er 30 år gammel.
# Aksesser attributter
print(person1.navn) # Kari
print(person2.alder) # 30Kva skjer her?
1. Vi definerer ein klasse med class Person:
2. Vi lagar ein konstruktør (__init__) som køyrer når objektet vert oppretta
3. Vi lagrar attributtar (navn og alder) på objektet med self.navn osv.
4. Vi definerer ein metode (hilse) som objektet kan bruke
5. Vi instansierer klassen to gonger for å lage to forskjellige Person-objekt
__init__.Syntaks:
def __init__(self, parameter1, parameter2, ...):
self.attributt1 = parameter1
self.attributt2 = parameter2
# ... annen oppsettskodeKonstruktøren vert brukt til:
- Setje startverdi for attributtar
- Initialisere objektet
- Køyre naudsynt oppsettskode
Kva er self?
Det mystiske self dukkar opp overalt i Python-klassar. Kva tyder det eigentleg?
self refererer til objektet sjølv – det objektet som metoden vert kalla på. Når du skriv person1.hilse(), er self inni hilse()-metoden lik person1.
Tenk på det slik: Når du seier "Eg går til butikken", refererer "eg" til deg sjølv. På same måte refererer self til objektet som "snakkar".
Kvifor må vi skrive self?
Python krev at du eksplisitt sender med objektreferansen som fyrste parameter i metodar. Dette gjer det tydeleg at metoden jobbar med objektets eigne data. Nokre språk (som Java) har this i staden, som fungerer automatisk.
Du kan gi attributtar standardverdiar i konstruktøren. Dette gjer det valfritt å sende inn verdien:
class Bankkonto:
def __init__(self, kontonummer, eier, saldo=0):
self.kontonummer = kontonummer
self.eier = eier
self.saldo = saldo
def vis_info(self):
print(f"Konto: {self.kontonummer}")
print(f"Eier: {self.eier}")
print(f"Saldo: {self.saldo} kr")
# Lag konto uten å oppgi saldo (bruker standard 0)
konto1 = Bankkonto("12345678", "Kari Nordmann")
konto1.vis_info()
# Konto: 12345678
# Eier: Kari Nordmann
# Saldo: 0 kr
# Lag konto med startsaldo
konto2 = Bankkonto("87654321", "Ola Nordmann", 5000)
konto2.vis_info()
# Konto: 87654321
# Eier: Ola Nordmann
# Saldo: 5000 krParameteren saldo=0 tyder at dersom brukaren ikkje oppgir ein saldo, vert han automatisk sett til 0.
Metodar som endrar objektet
Metodar kan ikkje berre lese attributtar – dei kan òg endre dei. Dette er ein av dei store fordelane med OOP: Objektet held styr på sin eigen tilstand.
Lat oss utvide Bankkonto-eksemplet:
class Bankkonto:
def __init__(self, kontonummer, eier, saldo=0):
self.kontonummer = kontonummer
self.eier = eier
self.saldo = saldo
def sett_inn(self, belop):
if belop > 0:
self.saldo += belop
print(f"Satt inn {belop} kr. Ny saldo: {self.saldo} kr")
else:
print("Beløpet må være positivt")
def ta_ut(self, belop):
if belop > self.saldo:
print("Ikke nok penger på konto")
elif belop <= 0:
print("Beløpet må være positivt")
else:
self.saldo -= belop
print(f"Tok ut {belop} kr. Ny saldo: {self.saldo} kr")
# Bruk
konto = Bankkonto("12345678", "Kari Nordmann", 1000)
konto.sett_inn(500) # Satt inn 500 kr. Ny saldo: 1500 kr
konto.ta_ut(200) # Tok ut 200 kr. Ny saldo: 1300 kr
konto.ta_ut(2000) # Ikke nok penger på kontoLegg merke til korleis metodane endrar self.saldo og òg validerer input. Dette er fornuftig logikk som høyrer heime i Bankkonto-klassen.
Fleire objekt av same klasse
Ein av styrkane ved klassar er at du kan lage mange objekt frå same mal. Kvart objekt har sine eigne attributtverdiar og er uavhengig av dei andre:
class Hund:
def __init__(self, navn, rase, alder):
self.navn = navn
self.rase = rase
self.alder = alder
def bjeff(self):
print(f"{self.navn}: Voff voff!")
def beskriv(self):
print(f"{self.navn} er en {self.alder} år gammel {self.rase}")
# Lag flere hunder
hund1 = Hund("Fido", "Golden Retriever", 3)
hund2 = Hund("Max", "Labrador", 5)
hund3 = Hund("Bella", "Schæfer", 2)
# Hver hund er et selvstendig objekt
hund1.beskriv() # Fido er en 3 år gammel Golden Retriever
hund2.beskriv() # Max er en 5 år gammel Labrador
hund3.bjeff() # Bella: Voff voff!
# Endre én hunds attributt påvirker ikke de andre
hund1.alder = 4
print(hund1.alder) # 4
print(hund2.alder) # 5 (uendret)Sjølv om alle tre objekta er Hund-objekt, har dei kvar sin navn, rase og alder.
Metodar som returnerer verdiar
Ikkje alle metodar skriv berre ut noko eller endrar objektet. Mange metodar returnerer ein verdi, akkurat som vanlege funksjonar:
class Rektangel:
def __init__(self, lengde, bredde):
self.lengde = lengde
self.bredde = bredde
def areal(self):
return self.lengde * self.bredde
def omkrets(self):
return 2 * (self.lengde + self.bredde)
def er_kvadrat(self):
return self.lengde == self.bredde
# Bruk
rekt = Rektangel(5, 3)
print(f"Areal: {rekt.areal()} cm²") # Areal: 15 cm²
print(f"Omkrets: {rekt.omkrets()} cm") # Omkrets: 16 cm
print(f"Kvadrat: {rekt.er_kvadrat()}") # Kvadrat: False
kvadrat = Rektangel(4, 4)
print(f"Kvadrat: {kvadrat.er_kvadrat()}") # Kvadrat: TrueMetodane areal(), omkrets() og er_kvadrat() reknar ut noko basert på attributtane til objektet og returnerer resultatet.
Klassar med samansette data
Attributtar i ein klasse kan vere kva som helst datatype – inkludert lister, ordbøker, eller til og med andre objekt!
class Handlekurv:
def __init__(self):
self.varer = [] # Tom liste
def legg_til(self, vare, pris):
self.varer.append({"vare": vare, "pris": pris})
print(f"La til {vare} i handlekurven")
def total_pris(self):
return sum(vare["pris"] for vare in self.varer)
def vis_innhold(self):
print("Handlekurv:")
for vare in self.varer:
print(f" - {vare['vare']}: {vare['pris']} kr")
print(f"Totalt: {self.total_pris()} kr")
# Bruk
kurv = Handlekurv()
kurv.legg_til("Melk", 20)
kurv.legg_til("Brød", 35)
kurv.legg_til("Ost", 80)
kurv.vis_innhold()
# Handlekurv:
# - Melk: 20 kr
# - Brød: 35 kr
# - Ost: 80 kr
# Totalt: 135 krHer bruker vi ei liste (self.varer) for å lagre ordbøker med vareinformasjon. Dette viser korleis OOP kan handtere kompleks data på ein ryddig måte.
Oppsummering
I dette kapittelet har du lært:
- Klasse vs. objekt: mal mot konkret instans.
- Konstruktoer (_init): køyrer når eit objekt vert laga.
- self: refererer til sjølve objektet.
- Attributtar og metodar: data og funksjonar i objektet.
- Fleire objekt: kvart objekt er sjølvstendig.
Noekkelbegreper
| Begrep | Forklaring |
|---|---|
| Klasse | Mal/blueprint for objekt |
| Objekt | Konkret instans av ein klasse |
| init_ | Konstruktoer som køyrer ved objektoppretting |
| self | Referanse til sjølve objektet |
Dette kapitlet er skrevet av Anthropics toppmodeller (Claude Opus og Claude Fable) og er foreløpig ikke manuelt gjennomgått — kvalitetskontrollen gjøres av uavhengige KI-agenter, og innmeldte feil rettes fortløpende. Funnet en feil? Meld fra, så retter vi den. Les mer om hvordan innholdet lages.