Hopp til innhold
Fagartikkel

Objekter og klasser

Objektorientert programmering er en retning innen programmering der det legges mer vekt på data, og dataenes egenskaper, framfor funksjoner og logikk. Objektorientert programmering ble utviklet på 1960-tallet og er i dag en del av de aller fleste programmeringsspråk.

Det første objektorienterte programmeringsspråket, Simula, ble utviklet ved Norsk Regnesentral på 1960-tallet av Ole-Johan Dahl og Kristen Nygaard. Simula hadde stor innflytelse på utviklingen av moderne programmeringsspråk som Java og C++. Uttrykket objektorientert programmering ble først brukt av Alan Kay i 1966.

Objekter er en datatype i programmering der vi kan samle flere biter informasjon i en og samme variabel. Dette er nyttig hvis vi har informasjon som henger sammen. Et eksempel på dette er om vi skal lage et bilspill der vi trenger informasjon om forskjellige biler. Om vi lagrer informasjon om en bil i atskilte variabler, kan det se slik ut:

Atskilte variabler
1let bilmerke = "Porsche";
2let modell = "911";
3let farge = "Svart"
4let toppfart = 290;
5let fart = 0;

Dette kan fungere om vi bare skal ha en bil, men det blir fort veldig mange variabler om vi skal ha med informasjon om flere biler, eller om vi skal ha mer informasjon om en bil. Vi kan heller lagre informasjonen om en bil som et objekt, slik:

Objekt
1const bil = {
2  bilmerke: "Porsche",
3  modell: "911",
4  farge: "Svart",
5  toppfart: 290,
6  fart: 0
7}
8

bil er da et objekt, og bilmerke, modell, farge, toppfart og fart kalles objektvariabler. Objektet behandles som en helhet, men vi kan også bruke de enkelte objektvariablene ved å angi objektets navn og objektvariabelen med punktum imellom, slik:

bil.bilmerke, bil.modell, bil.farge

For eksempel vil console.log(bil.farge); gi utskriften Svart.

Klasser

Hvis vi skal lage flere like objekter, kan vi lage en klasse. En klasse kan beskrives som en generell beskrivelse av et objekt. I en klasse angir vi alle objektvariablene som objekter av samme klasse skal ha.

Klasse
1class Bil{
2
3  constructor(bilmerke, modell, farge, toppfart, fart) {
4    this.bilmerke = bilmerke;
5    this.modell = modell;
6    this.farge = farge;
7    this.toppfart = toppfart;
8    this.fart = fart;
9  }
10  
11}

En klasse inneholder en konstruktør (constructor). Dette er en slags funksjon som oppretter objektet, men det er verdt å merke seg at en funksjon som ligger inne i en klasse, ofte kalles en metode. Vi kan opprette bilen fra eksempelet over via klassen Bil, slik:

Oprette nytt objekt
1const bil = new Bil("Porsche", "911", "svart", 290, 0);

Når du skriver new Bil("Porsche", "911", "svart", 290, 0), påkalles konstruktørmetoden, og verdiene inne i parentesen blir sendt til konstruktøren. Inne i konstruktøren er det flere linjer som starter med this, for eksempel this.bilmerke = bilmerke. Dette betyr at verdien for objektvariabelen bilmerke til det nye objektet (this.bilmerke) settes lik verdien for variabelen bilmerke som er sendt inn til konstruktørmetoden (bilmerke). this er et nøkkelord som viser tilbake til det objektet som har kalt en metode.

Metoder

Vi kan også lage funksjoner inne i en klasse, som bare kan påkalles av klassens objekter. Dette er en metode. I Bil-klassen kan vi for eksempel ha en metode som returnerer en beskrivelse av bilen, slik:

Metode: presenter()
1class Bil {
2
3  constructor(bilmerke, modell, farge, toppfart, fart) {
4    this.bilmerke = bilmerke;
5    this.modell = modell;
6    this.farge = farge;
7    this.toppfart = toppfart;
8    this.fart = fart;
9  }
10  
11  presenter() {
12    return `Denne bilen er en ${this.farge} ${this.bilmerke} ${this.modell},\
13    med en toppfart på ${this.toppfart} km/h.\
14    Akkurat nå har den en fart på ${this.fart} km/h.`
15    //Vi bruker linjeskift i koden for å forbedre lesbarheten.
16    //Backslash \ brukes for å unngå at det blir linjeskift i utskriften.
17  }
18
19}

For å påkalle metoden må vi påkalle den med bil-objektet, slik:

let bilInfo = bil.presenter(); (Siden metoden returnerer en tekst, må vi lagre resultatet i en variabel.)

console.log(bilInfo); vil gi denne utskriften i konsollen:

Denne bilen er en svart Porsche 911, med en toppfart på 290 km/h. Akkurat nå har den en fart på 0 km/h.

Vi kan også bruke metoder for å endre verdier på objektvariablene. For eksempel kan vi lage en metode for å endre fart på bilen, så vi kan simulere at bilen gir gass.

Metode: giGass
1class Bil {
2
3  constructor(bilmerke, modell, farge, toppfart, fart) {
4    this.bilmerke = bilmerke;
5    this.modell = modell;
6    this.farge = farge;
7    this.toppfart = toppfart;
8    this.fart = fart;
9  }
10  
11  presenter() {
12    return `Denne bilen er en ${this.farge} ${this.bilmerke} ${this.modell},\
13    med en toppfart på ${this.toppfart} km/h.\
14    Akkurat nå har den en fart på ${this.fart} km/h.`
15    //Vi bruker linjeskift i koden for å forbedre lesbarheten.
16    //Backslash \ brukes for å unngå at det blir linjeskift i utskriften.
17  }
18  
19  giGass() {
20    if (this.fart + 2 <= this.toppfart) {
21      this.fart = this.fart + 2;
22    }
23  }
24
25}

Metoden giGass øker farten til bilen med 2 km/h, så lenge økningen ikke overskrider toppfarten. Denne metoden kan knyttes til en knapp eller en tast på tastaturet som kan fungere som en gasspedal.

Samle mange objekter i ei liste (array)

En av grunnene til at vi bruker klasser, er at vi kan lage mange objekter av samme type. En måte å gjøre dette på er å lagre ett og ett objekt som variabler, slik:

deklarere ett og ett objekt
1const porsche = new Bil("Porsche", "911", "svart", 290, 0);
2const ferrari = new Bil("Ferrari", "F8 Spider", "rød", 340, 0);
3const ford = new Bil("Ford", "Mustang Mach 1", "blå", 270, 0);

En mer effektiv måte er å legge objektene i ei liste, slik:

Legge objektene i ei liste
1const biler = [];
2biler.push( new Bil("Porsche", "911", "svart", 290, 0) );       //biler[0]
3biler.push( new Bil("Ferrari", "F8 Spider", "rød", 340, 0) );   //biler[1]
4biler.push( new Bil("Ford", "Mustang Mach 1", "blå", 270, 0) ); //biler[2]

På denne måten slipper du å lage egne variabelnavn for hver bil, siden de i stedet får hver sin indeks i lista. En fordel med dette er at det blir mye mer fleksibelt å legge til nye objekter, for eksempel fra et webgrensesnitt, og du slipper å bestemme på forhånd hvor mange objekter som skal opprettes.

For å hente ut info om enkeltbiler må vi huske å bruke indeksen i lista. Skal vi hente ut toppfarten til Ferrarien, må vi skrive biler[1].toppfart, og om vi skal gi gass til Porschen, må vi skrive biler[0].giGass();.

Skrevet av Karl Arne Dalsaune.
Sist faglig oppdatert 22.03.2022