22 Objektorientert programmering
Grunnleggende OOP-konsepter: klasser, objekter, metoder og arv.
Kva er objektorientert programmering?
Objektorientert programmering (OOP) er ein måte å strukturere kode på ved å modellere "ting" frå den verkelege verda som objekt.
Kvifor OOP?
- Betre organisering av kode
- Lettare å gjenbruke kode
- Enklare å vedlikehalde store program
- Naturleg måte å tenkje på problem
Grunnleggjande omgrep:
Klasse
Ei "oppskrift" eller mal for å lage objekt. Definerer kva eigenskapar (attributt) og handlingar (metodar) objekta skal ha.
Objekt (instans)
Ei konkret "ting" laga frå ein klasse. Kvart objekt har sine eigne verdiar for attributta.
Eksempel frå verkelegheita:
- Klasse: "Sensor" (generell oppskrift)
- Objekt: temperatursensor1, temperatursensor2, fuktighetssensor1
Attributt
Eigenskapar/data som objektet har:
- sensor.verdi = 23.5
- sensor.type = "temperatur"
- sensor.enhet = "celsius"
Metodar
Handlingar objektet kan utføre:
- sensor.les()
- sensor.kalibrer()
- sensor.rapport()
Definere klassar i Python
Grunnleggjande klassesyntaks:
class Sensor:
"""En klasse som representerer en sensor."""
def __init__(self, sensor_id, sensor_type):
"""Konstruktør - kjøres når objekt opprettes."""
self.sensor_id = sensor_id
self.sensor_type = sensor_type
self.verdi = 0.0
self.aktiv = True
def les_verdi(self):
"""Leser og returnerer sensorverdien."""
# I virkeligheten ville dette lese fra hardware
return self.verdi
def sett_verdi(self, ny_verdi):
"""Setter en ny verdi (for simulering)."""
self.verdi = ny_verdi
def __str__(self):
"""Returnerer tekstrepresentasjon."""
return f"{self.sensor_type} ({self.sensor_id}): {self.verdi}"Opprette objekt:
# Lage sensor-objekter
temp_sensor = Sensor("T001", "temperatur")
fukt_sensor = Sensor("H001", "fuktighet")
# Bruke objektene
temp_sensor.sett_verdi(23.5)
fukt_sensor.sett_verdi(65)
print(temp_sensor.les_verdi()) # 23.5
print(fukt_sensor) # fuktighet (H001): 65self-parameteren:
- Refererer til objektet sjølv
- Må vere første parameter i alle metodar
- Blir brukt for å få tilgang til attributt og andre metodar
Metodar og attributt
Instansattributt
Tilhøyrer kvart enkelt objekt.
class Motor:
def __init__(self, pin):
self.pin = pin # Instansattributt
self.hastighet = 0 # InstansattributtKlasseattributt
Blir delte mellom alle objekt av klassen.
class Motor:
antall_motorer = 0 # Klasseattributt
def __init__(self, pin):
self.pin = pin
Motor.antall_motorer += 1
m1 = Motor(5)
m2 = Motor(6)
print(Motor.antall_motorer) # 2Private attributt (konvensjon)
Attributt som startar med eller _ er meinte som "private".
class Konto:
def __init__(self, saldo):
self._saldo = saldo # "Privat" - bruk med forsiktighet
def ta_ut(self, belop):
if belop <= self._saldo:
self._saldo -= belop
return True
return False
def vis_saldo(self):
return self._saldoProperty-dekoratøren
Kontrollert tilgang til attributt.
class Temperatur:
def __init__(self, celsius):
self._celsius = celsius
@property
def celsius(self):
return self._celsius
@celsius.setter
def celsius(self, verdi):
if verdi < -273.15:
raise ValueError("Under absolutt null!")
self._celsius = verdi
@property
def fahrenheit(self):
return self._celsius * 9/5 + 32
t = Temperatur(20)
print(t.celsius) # 20
print(t.fahrenheit) # 68.0
t.celsius = 25 # Setter via propertyArv og polymorfisme
Arv
Ein klasse kan arve frå ein annan og få alle eigenskapane hans.
class Sensor:
"""Baseklasse for alle sensorer."""
def __init__(self, sensor_id):
self.sensor_id = sensor_id
self.verdi = 0.0
def les(self):
return self.verdi
class TemperaturSensor(Sensor):
"""Arvende klasse - temperaturspesifikk."""
def __init__(self, sensor_id, enhet="celsius"):
super().__init__(sensor_id) # Kall foreldres konstruktør
self.enhet = enhet
def les_formatert(self):
return f"{self.verdi} °{'C' if self.enhet == 'celsius' else 'F'}"
class FuktighetsSensor(Sensor):
"""Arvende klasse - fuktighetsspesifikk."""
def les_formatert(self):
return f"{self.verdi} %RH"super()
Blir brukt for å kalle metodar frå foreldreklassen.
Polymorfisme
Objekt av forskjellige klassar kan behandlast likt.
def les_alle_sensorer(sensorer):
for sensor in sensorer:
print(sensor.les_formatert()) # Fungerer for alle sensortyper!
temp = TemperaturSensor("T001")
fukt = FuktighetsSensor("H001")
temp.verdi = 23.5
fukt.verdi = 65
les_alle_sensorer([temp, fukt])
# 23.5 °C
# 65 %RHFordelar med arv:
- Unngår kodeduplisering
- Logisk hierarki
- Lettare å utvide funksjonalitet
Definer ein klasse LED med attributta pin og status (på/av), og metodar for slaapaa(), slaaav() og toggle().
Kva er skilnaden mellom ein klasse og eit objekt?
Lag ein klasse DCMotor med attributt for pin og hastigheit (-100 til 100), og metodar for sett_hastighet(n), stopp(), og retning().
Forklar kva self tyder i Python-klassar.
Kva gjer super()._init_() og når blir det brukt?
Design eit klassehierarki for eit smarthus-system. Lag ein baseklasse SmartEnhet og arva klassar for SmartLys, SmartTermostat og SmartLaas. Inkluder relevante attributt og metodar.
Lag ein klasse SensorLogg som held styr på målingar over tid. Han skal kunne legge til målingar med tidsstempel, hente siste n målingar, rekne ut gjennomsnitt, og finne min/max.
Oppgaver
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.