I objektorienteret programmering , den erklæring af en klasse samler medlemmer, metoder og egenskaber (attributter) fælles for et sæt af objekter .
Klassen erklærer på den ene side attributter, der repræsenterer objekternes tilstand og på den anden side metoder, der repræsenterer deres adfærd.
En klasse repræsenterer derfor en kategori af objekter. Det ser også ud som en form eller en fabrik, hvorfra det er muligt at skabe objekter; det er på en måde en "værktøjskasse", der giver dig mulighed for at skabe et objekt. Vi taler derefter om et objekt som en forekomst af en klasse (oprettelse af et objekt med klassens egenskaber).
Det er muligt at begrænse det sæt objekter, der er repræsenteret af en klasse A takket være en arvemekanisme . I dette tilfælde opretter vi en ny klasse B, der er knyttet til klasse A, og som tilføjer nye egenskaber. I dette tilfælde anvendes forskellige udtryk:
I eksemplerne nedenfor definerer vi på forskellige sprog en klasse Pointmed to attributter xog y. Denne klasse indeholder:
Den konstruktør er en regel i initialisering procedurer, der vil blive kaldt, når du opretter en ny instans af en klasse. Den definerer en første gyldig tilstand for objektets interne tilstand. Denne regel kan oversættes kort med begrebet "erklæring af strukturer, af variabler". Der kan være flere erklærede konstruktører. I mangel af en konstruktør genererer compileren en som standard.
Den metode er en processuel regel anvendes på attributterne for klassen. Denne regel kan oversættes kort med begrebet "funktion" eller "rutine". Der kan være flere metoder i en klasse. Metoderne er nøgleelementerne i klassen.
Fra og med 2015-udgaven ( ECMAScript 6 ) er der tilføjet en klassedefinitionssyntaks, der forenkler brugen af dens prototypiske arvemekanisme til objektorienteret udvikling:
class Point { constructor(x, y) { this._x = x; this._y = y; } getX() { return this._x; } getY() { return this._y; } isOrigin() { return this._x === 0 && this._y === 0; } translate(pt) { return new Point(this._x + pt._x, this._y + pt._y); } }En klasse siges at være uforanderlig, hvis det ikke er muligt at ændre et objekt af denne klasse efter dets oprettelse. F.eks. Er Point-klassen, beskrevet ovenfor på forskellige sprog, uforanderlig, fordi den ikke udsætter nogen metode til at ændre værdien af dens medlemsvariabler. Metoden translatereturnerer et nyt objekt i stedet for at ændre selve objektet. Klassen java.lang.Stringi Java-miljøet er et andet eksempel på uforanderlig klasse, som klassen System.Stringi Framework Microsoft .NET .
På nogle sprog kan en klasse delvist defineres. Især har nogle metoder i denne klasse intet organ eller implementering. Disse metoder kaldes "abstrakt" (eller virtuelt i C ++ ).
Klasser med mindst en abstrakt metode kaldes også abstrakte (eller virtuelle) klasser og kan ikke instantieres direkte - undtagen ved at oprette en ikke-abstrakt underklasse.
Eksempel Vi vil modellere objektrelationerne for en vektortegning. Vi kan sige, at et tegneobjekt er et sæt geometrier (den abstrakte klasse), og hver geometri kan være et punkt, en polygon eller en brudt linje (disse tre klasser arver fra geometri). Den abstrakte klasse er derfor ikke essentiel i sig selv, men den er essentiel for en ren, generisk og forenklet model.Den MixIn er et særligt tilfælde af en abstrakt klasse. Det gør det muligt at tilføje en tjeneste til underklasser.
En klasse, der kun har abstrakte metoder, kaldes en rent virtuel grænseflade eller klasse (i C ++) eller protokol (i mål C ).
Klassen i en klasse er en metaklasse . Metaclasses muliggør strukturel refleksion .
En klasse, som defineret tidligere, er et sæt medlemmer (metoder og attributter), som man nødvendigvis skal håndtere. Hvis p er en forekomst af punkt (a, b), hvor a og b er af typen int , får vi adgang til medlemmerne af p sådan:
Spørgsmålet, der straks kommer til at tænke, er følgende: hvorfor definere en getX () -metode , når vi direkte kan få adgang til x- og y- felterne i Point- klassen ?
Faktisk, når man skal håndtere mange klasser såvel som mange forhold mellem disse klasser (jf. Arv ), kan skemaet, dataene og operationerne blive meget komplekse (især for en person, der ikke har designet det kodede). Vi benytter os derfor af en mekanisme kaldet datakapsling , som er ansvarlig for at skjule klassens felter fra visse dele af programmet af hensyn til integriteten. Brugeren skal derfor kun manipulere metoder, der er godkendt, og som i teorien udfører deres rolle godt.
I henhold til indkapslingsprincippet har metoder offentlig adgang - det betyder, at ethvert element i et program kan bruge en metode. Med hensyn til tilstandskomponentattributterne får de adgang til private ( private ) - Kun selve objektet (og dermed de metoder, det indeholder) har direkte adgang til dets attributter. I dette tilfælde er den eneste måde at få adgang til disse attributter på at bruge objektets metoder. Attributterne kan ikke bruges direkte af et andet element i programmet eller endda et andet objekt, selvom dette objekt er af samme klasse. Et andet punkt: alle attributter for et objekt, der nedarves, er direkte tilgængelige af de andre medlemmer af dette objekt.
Med hensyn til de sidste bemærkninger er der ofte forvirring omkring semantikken i privat adgang. Princippet om indkapsling indebærer en beskyttelse af de attributter, som vi vil kalde lodrette (kun objektet selv og objekterne i en underklasse har adgang til det). Vi finder denne semantik på sprog som Smalltalk , Oz eller OCaml . Visse sprog, som C ++ , Pascal eller Java , beder dog om beskyttelse af de attributter, som vi vil kalde vandrette (objekterne i samme klasse har adgang til det, men ikke objekterne i underklasserne).
Nogle sprog tillader, når de erklærer en klasse, at ændre omfanget af dets medlemmer og følgelig medlemmerne af objekter, der er instantieret fra denne klasse; ændring af omfanget reducerer synlighed og dermed tilgængelighed for medlemmer.
For eksempel er C ++ og Object Pascal sprog tilbyde følgende scope ændringer :
Anvendelsesområde | Nøgleord | Synlig (tilgængelig) af | Bemærk | ||
---|---|---|---|---|---|
(sigtbarhed) | i C ++ | et klassemedlem | en afledt klasse | en klient af objektet | |
offentlig | public | Ja | Ja | Ja | De offentlige medlemmer er lige så tilgængelige som det klassificerede objekt i denne klasse (medlemmerne, der er erklæret i dette omfang, er synlige og anvendelige af objektets klient). |
beskyttet | protected | Ja | Ja | ingen | Beskyttede medlemmer har kun adgang til medlemmer af det klassificerede objekt i denne klasse og af klasser, der stammer fra det. |
privat | private | Ja | ingen | ingen | Private medlemmer er kun tilgængelige for medlemmer af det klassificerede objekt i denne klasse (de er ikke tilgængelige af en underklasse eller objektets klient). |
De semantik af disse omfang ændringer og deres antal varierer afhængigt af programmeringssprog.
For eksempel tilbyder Java en lidt anden definition for beskyttede medlemmer; det strækker sig til alle objekter i samme klasse, underklasser og klasser i samme pakke.
For eksempel giver Python muligheden for at ændre synligheden af medlemmerne af en klasse ved at præfikse navnet på medlemmet med understregningstegnet ('_'):
Når vi skal håndtere data af samme type (det er f.eks. Tilfældet med punkter i et koordinatsystem), vil vi muligvis anvende operationer på disse objekter (i betydningen OOP). Således giver fusionen af to zoner (polygoner) en ny zone, ligesom tilføjelsen af to punkter giver et nyt punkt.
Lad os fortsætte på vores Point-klasse. Følgende Python-eksempel er meget fortællende:
class Point: (...) def __add__(self,point): # Surcharge de '+' return Point(self.x + point.x, self.y + point.y) p=Point(0,0) q=Point(2,3) r=p+qSå r.getX () returnerer 2.