Objekt og klassar - Utvikling (IM-ITK vg2) - NDLA

Hopp til innhald
Fagartikkel

Objekt og klassar

Objektorientert programmering er ei retning innan programmering der det blir lagt meir vekt på data, og eigenskapane til dataa, framfor funksjonar og logikk. Objektorientert programmering vart utvikla på 1960-talet og er i dag ein del av dei aller fleste programmeringsspråka.

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

Objekt er ein datatype i programmering der vi kan samle fleire bitar informasjon i ein og same variabel. Dette er nyttig viss vi har informasjon som heng saman. Eit døme på dette er om vi skal lage eit bilspel der vi treng informasjon om ulike bilar. Om vi lagrar informasjon om ein bil i åtskilde variablar, kan det sjå slik ut:

Åtskilde variablar
1let bilmerke = "Porsche";
2let modell = "911";
3let farge = "Svart"
4let toppfart = 290;
5let fart = 0;

Dette kan fungere om vi berre skal ha ein bil, men det blir fort veldig mange variablar om vi skal ha med informasjon om fleire bilar, eller om vi skal ha meir informasjon om ein bil. Vi kan heller lagre informasjonen om ein bil som eit objekt, slik:

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

bil er då eit objekt, og bilmerke, modell, farge, toppfart og fart er objektvariablar. Objektet blir behandla som ein heilskap, men vi kan òg bruke dei enkelte objektvariablane ved å skrive namnet til objektet og objektvariabelen med punktum imellom, slik:

bil.bilmerke, bil.modell, bil.farge

Til dømes vil console.log(bil.farge); gi utskrifta Svart.

Klassar

Dersom vi skal lage fleire like objekt, kan vi lage ein klasse. Ein klasse er ei generell beskriving av eit objekt. I ein klasse angir vi alle objektvariablane som objekt av same 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}

Ein klasse inneheld ein konstruktør (constructor). Dette er ein slags funksjon som opprettar objektet, men det er verd å merke seg at ein funksjon som ligg inne i ein klasse, ofte blir kalla ein metode. Vi kan opprette bilen frå dømet over via klassen Bil, slik:

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

Når du skriv new Bil("Porsche", "911", "svart", 290, 0), blir konstruktørmetoden kalla på, og verdiane inne i parentesen blir sende til konstruktøren. Inne i konstruktøren er det fleire linjer som startar med this, til dømes this.bilmerke = bilmerke. Dette betyr at verdien for objektvariabelen bilmerke til det nye objektet (this.bilmerke) blir sett lik verdien for variabelen bilmerke som er send inn til konstruktørmetoden (bilmerke). this er eit nøkkelord som viser tilbake til det objektet som har kalla på ein metode.

Metodar

Vi kan òg lage funksjonar inne i ein klasse, som berre kan påkallast av objekta til klassen. Dette er ein metode. I Bil-klassen kan vi til dømes ha ein metode som returnerer ei beskriving 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 ein ${this.farge} ${this.bilmerke} ${this.modell},\
13    med ein toppfart på ${this.toppfart} km/h.\
14    Akkurat no har han ein fart på ${this.fart} km/h.`
15    //Vi bruker linjeskift i koden for å betre lesbarheita.
16    //Backslash \ bruker vi for å unngå at det blir linjeskift i utskrifta.
17  }
18
19}

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

let bilinfo = bil.presenter(); (Sidan metoden returnerer ein tekst, må vi lagre resultatet i ein variabel.)

console.log(bilinfo); vil gi denne utskrifta i konsollen:

Denne bilen er ein svart Porsche 911, med ein toppfart på 290 km/h. Akkurat no har han ein fart på 0 km/h.

Vi kan òg bruke metodar for å endre verdiar på objektvariablane. Til dømes kan vi lage ein 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 ein ${this.farge} ${this.bilmerke} ${this.modell},\
13    med ein toppfart på ${this.toppfart} km/h.\
14    Akkurat no har han ein fart på ${this.fart} km/h.`
15    //Vi bruker linjeskift i koden for å betre lesbarheita.
16    //Backslash \ bruker vi for å unngå at det blir linjeskift i utskrifta.
17  }
18  
19  giGass() {
20    if (this.fart + 2 <= this.toppfart) {
21      this.fart = this.fart + 2;
22    }
23  }
24
25}

Metoden giGass aukar farten til bilen med 2 km/h, så lenge auken ikkje overskrid toppfarten. Denne metoden kan knytast til ein knapp eller ein tast på tastaturet som kan fungere som ein gasspedal.

Samle mange objekt i ei liste (array)

Ein av grunnane til at vi bruker klassar, er at vi kan lage mange objekt av same type. Ein måte å gjere dette på er å lagre eitt og eitt objekt som variablar, slik:

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

Ein meir effektiv måte er å legge objekta i ei liste, slik:

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

På denne måten slepp du å lage eigne variabelnamn for kvar bil, sidan dei i staden får kvar sin indeks i lista. Ein fordel med dette er at det blir mykje meir fleksibelt å legge til nye objekt, til dømes frå eit webgrensesnitt, og du slepp å bestemme på førehand kor mange objekt som skal opprettast.

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

Skrive av Karl Arne Dalsaune.
Sist fagleg oppdatert 22.03.2022