Tilbake
2.1
Komposisjon og aggregering

2.1 Komposisjon og aggregering

Bygge komplekse objekter med komposisjon.

60 min
6 oppgaver
KomposisjonAggregeringHas-a-relasjon
Du leser den lesevennlige versjonen
Din fremgang i kapitlet
0 / 6 oppgaver

Har-en, ikke er-en

Du har lært om arv, der en klasse er en spesialisering av en annen. Men svært ofte er det noe annet vi egentlig vil uttrykke: at en klasse har en annen som en del av seg selv. En bil er ikke en motor – men en bil har en motor. Denne tankegangen kalles komposisjon, og er et kraftig alternativ til arv.

Komposisjon er når ett objekt inneholder ett eller flere andre objekter som en del av sin tilstand. I stedet for at Bil arver fra Motor, lar vi Bil lage og holde et Motor-objekt:

class Motor:
    def __init__(self, hestekrefter):
        self.hestekrefter = hestekrefter
    def start(self):
        print(f"Motor med {self.hestekrefter} hk startet!")

class Bil:
    def __init__(self, merke, hestekrefter):
        self.merke = merke
        self.motor = Motor(hestekrefter)  # komposisjon
    def start_bil(self):
        self.motor.start()  # delegering

Legg merke til to begreper her. Selve det at bilen inneholder en motor er komposisjon. Det at bilen overlater startoppgaven til motoren, i stedet for å gjøre den selv, kalles delegering. Bilen sier i praksis: «motor, start deg selv» – og slipper å vite hvordan.

📝Oppgave Quiz 1

Hvorfor komposisjon ofte slår arv

Det finnes et velkjent designprinsipp: «favor composition over inheritance» – foretrekk å bygge funksjonalitet ved å kombinere objekter framfor å arve oppførsel. Hvorfor? Komposisjon er mer fleksibel, fordi du kan endre oppførsel mens programmet kjører. Den gir løsere kobling, fordi objektene er mindre avhengige av hverandre. Den gjør testing enklere, fordi du kan bytte ut deler. Og den unngår problemene med dype, stive arvshierarkier.

Et klassisk eksempel er en and. Med arv kunne du la And arve fra både Flygende og Svømmende. Men hva om du senere vil ha en and som ikke kan fly? Da må du lage en helt ny klasse. Med komposisjon gir du anden en flyteknikk og en svømmeteknikk som objekter:

class And:
    def __init__(self, fly_oppførsel, svøm_oppførsel):
        self.fly_oppførsel = fly_oppførsel
        self.svøm_oppførsel = svøm_oppførsel
    def fly(self):
        self.fly_oppførsel.utfør()

Nå kan du lage And(FlyOppførsel(), SvømOppførsel()) for en vanlig and, eller And(IngenFlyOppførsel(), SvømOppførsel()) for en and som ikke kan fly. Du bytter oppførsel uten å lage nye klasser. Det er fleksibiliteten komposisjon gir.

📝Oppgave Quiz 2

Komposisjon, aggregering og delegering i praksis

Innenfor komposisjon finnes det en gradsforskjell som er verdt å kjenne til. Ekte komposisjon er en tett kobling der delene ikke kan eksistere uten helheten. Et hjerte gir ikke mening uten en person; lager Person-klassen selv sitt Hjerte i konstruktøren, forsvinner hjertet når personen forsvinner. Aggregering er en svakere variant, en løsere kobling der delene kan leve uavhengig. Fire Hjul-objekter kan lages utenfor bilen og sendes inn til den – hjulene eksisterer fortsatt selv om bilen slettes. I praksis brukes ofte begge ordene om hverandre, men forskjellen ligger i hvem som «eier» delene og om de kan leve på egen hånd.

Komposisjon skinner når du setter sammen et system av samarbeidende deler. Et spill kan ha et grafikk-objekt, et lyd-objekt og et inndata-objekt, og delegere oppgaver til hver av dem: grafikken tegner skjermen, lyden spiller effekter, inndata leser tastetrykk. Spill-klassen koordinerer, men gjør ikke alt selv. Tilsvarende følger en Smarttelefon komposisjonsprinsippet best når den inneholder et Kamera, en GPS og en Skjerm som attributter – ikke ved å arve fra dem alle gjennom multippel arv. Husk samtidig at arv fortsatt er riktig verktøy når relasjonen virkelig er er-en: en hund er et dyr, og det forblir et arvsforhold.

📝Oppgave Quiz 3

Oppsummering

Vi gikk fra «er-en» til «har-en». Komposisjon betyr at en klasse inneholder objekter av andre klasser som del av sin tilstand, og delegering er å overlate ansvar til disse innebygde objektene i stedet for å gjøre alt selv. Aggregering er en svakere, løsere variant der delene kan eksistere uavhengig av helheten.

Designprinsippet «favor composition over inheritance» minner oss om at komposisjon ofte er det beste valget: den gir mer fleksibilitet, løsere kobling og enklere testing, og lar oss endre oppførsel under kjøring – som anden som kan bytte flyteknikk uten å bli en ny klasse. Men arv har fortsatt sin plass når relasjonen virkelig er er-en, som at en hund er et dyr. I neste kapittel skal vi bruke komposisjon til å bygge datastrukturer.

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.