MySQL Java JavaScript PHP Python HTML-CSS C-sharp C++ Go

OOP - Clase

Clase

Cu introducerea standardului ES2015 (ES6) în JavaScript, a apărut o nouă modalitate de a defini obiecte - folosind clasele. O "clasă" reprezintă o descriere a unui obiect, a stării și comportamentului său, în timp ce un "obiect" este o instanță concretă sau exemplar al clasei. Practic, sintaxa claselor este o construcție alternativă care, asemenea funcțiilor constructor, permite definirea unui nou tip de obiecte.

Trebuie de menționat că, în ciuda suportului pentru clase, JavaScript nu este un limbaj de programare orientat pe obiect clasic, cum ar fi Java sau C#. Clasele JavaScript sunt esențialmente ceea ce se numește "zahăr sintactic" peste funcțiile constructor - construcții mai comode pentru crearea obiectelor. În realitate, în JavaScript, obiectele sunt create încă nu pe baza claselor, ci pe baza obiectelor sau prototipurilor.

Definirea unei clase

Pentru a defini o clasă, se folosește cuvântul cheie class:

class Person{ }

După cuvântul "class", urmează numele clasei (în acest caz, clasa se numește Person), și apoi în acolade se definește corpul clasei.

Acesta este cel mai comun mod de a defini o clasă. Cu toate acestea, există și alte modalități. De exemplu, se poate defini o clasă anonimă și apoi să-i fie atribuită unei variabile sau constante:

const Person = class{}

În principiu, putem crea o clasă și să o atribuim unei variabile sau constante:

const User = class Person{}

Crearea obiectelor

O clasă este o reprezentare generală a unor entități sau obiecte. O instanță specifică a acestei reprezentări, a clasei, este un obiect. După definirea clasei, putem crea obiecte ale clasei cu ajutorul unui constructor:

class Person{}

const tom = new Person();
const bob = new Person();

Pentru a crea un obiect cu ajutorul constructorului, începeți cu cuvântul cheie `new`. Apoi, efectiv, aveți apelul constructorului - practic, apelul funcției cu numele clasei. În mod implicit, clasele au un constructor fără parametri. Prin urmare, în acest caz, la apelul constructorului nu sunt transmise argumente.

Este de remarcat faptul că, spre deosebire de funcții, pentru a utiliza o clasă, trebuie să o definiți mai întâi. De exemplu, în următorul cod, nu vom obține o eroare, deoarece clasa Person este definită în prealabil:

const tom = new Person();   // ! Eroare- Uncaught ReferenceError: Cannot access 'Person' before initialization

class Person{}
}

Dacă definiția clasei este atribuită unei variabile sau constante, putem utiliza numele acelei variabile/constante pentru a crea obiecte ale clasei:

const User = class Person{}
const tom = new User();
console.log(tom);

În exemplul de mai sus, deși folosim apelul `new User()`, obiectul creat va reprezenta de fapt clasa `Person`.

Exemplu de creare a unui obiect pentru o clasă anonimă:

const Person = class{}
const tom = new Person();
console.log(tom);

Câmpurile și proprietățile clasei

Câmpurile și proprietățile sunt utilizate într-o clasă pentru a stoca date sau stări ale obiectului.

Deci, mai sus a fost definită clasa `Person`, care reprezenta o persoană. O persoană are caracteristici distinctive, cum ar fi numele și vârsta. Să definim în clasa `Person` câmpurile pentru stocarea acestor date:

class Person{
   name;
   age;
}
const tom = new Person();
tom.name = "Tom";
tom.age = 37;
console.log(tom.name);  // Tom
console.log(tom.age);   // 37

Definirea unui câmp constă efectiv în a-i specifica numele:

name;
age;

Astfel, aici este definit câmpul `name` pentru a stoca numele persoanei și câmpul `age` pentru a stoca vârsta persoanei.

După crearea obiectului clasei, putem accesa aceste câmpuri. Pentru aceasta, după numele obiectului, se folosește punctul și se specifică numele câmpului:

tom.name = "Tom";       // setăm valoarea câmpului
console.log(tom.name);  // obținem valoarea proprietății

În exemplul de mai sus, câmpurile clasei pot fi de asemenea numite proprietăți. În esență, proprietățile reprezintă câmpuri publice sau accesibile din exterior ale clasei. Mai departe, vom analiza detaliat când câmpurile sunt necomunicative, adică inaccesibile din exterior.

Dar până atunci, este important să înțelegem că proprietățile și câmpurile publice sunt unul și același lucru. În exemplul de mai sus, câmpurile `name` și `age` pot fi de asemenea numite proprietăți.

La nevoie, putem atribui câmpurilor anumite valori inițiale:

class Person{
   name = "Unknown";
   age= 18;
}
const tom = new Person();
console.log(tom.name);  // Unknown
tom.name = "Tom";
console.log(tom.name);  // Tom

Comportamentul clasei și metodele sale

În afară de stocarea datelor care definesc starea unui obiect, o clasă poate să aibă metode care definesc comportamentul obiectului - acțiunile pe care obiectul le poate realiza. De exemplu, să definim în clasa Person câteva metode:

class Person{
   name;
   age;
   move(place){
       console.log(`Go to ${place}`);
   }
   eat(){
       console.log("Eat apples");
   }
}
const tom = new Person();
tom.move("Hospital");   // Go to Hospital
tom.move("Cinema");     // Go to Cinema
tom.eat();              // Eat apples

Aici este definită metoda `move()`, care reprezintă o deplasare convențională a persoanei. Ca parametru, metoda primește locul către care se îndreaptă persoana. A doua metodă - `eat()` - reprezintă un proces convențional de alimentare.

Cum putem accesa câmpurile și metodele în cadrul clasei? Folosind cuvântul cheie `this`. În acest context, `this` indică obiectul curent.

De exemplu, să definim o metodă care afișează informații despre obiect:

class Person{
   name;
   age;
   print(){
       console.log(`Name: ${this.name}  Age: ${this.age}`);
   }
}
const tom = new Person();
tom.name = "Tom";
tom.age = 37;
tom.print();    // Name: Tom  Age: 37

const bob = new Person();
bob.name = "Bob";
bob.age = 41;
bob.print();    // Name: Bob  Age: 41

Definirea constructorului

Pentru a crea un obiect al unei clase se utilizează constructorul:

const bob = new Person();

Apelul constructorului implicit, care există în clase, reprezintă de fapt apelul unei metode care are același nume cu clasa și întoarce un obiect al acelei clase.

De asemenea, putem defini propriile noastre constructori în clase:

class Person {
   name;
   age;
   constructor() {
       console.log("Apelarea constructorului");
   }
   print() {
       console.log(`Nume: ${this.name}  Vârstă: ${this.age}`);
   }
}
const tom = new Person();   // Apelarea constructorului
const bob = new Person();   // Apelarea constructorului

Constructorul este definit prin intermediul metodei cu numele constructor. Practic, acesta este un simplu metodă care poate primi parametri. În cazul de față, constructorul afișează un mesaj pe consolă. Prin urmare, la executarea liniei

const tom = new Person();

Vom vedea în consola browser-ului mesajul corespunzător.

De obicei, scopul constructorului este de a inițializa obiectul cu anumite date inițiale.

class Person{
   name;
   age;
   constructor(pName, pAge){
       this.name = pName;
       this.age = pAge;
   }
   print(){
       console.log(`Name: ${this.name}  Age: ${this.age}`);
   }
}
const tom = new Person("Tom", 37);
tom.print();    // Name: Tom  Age: 37
const bob = new Person("Bob", 41);
bob.print()     // Name: Bob  Age: 41

Aici, constructorul primește doi parametri și le atribuie valorile câmpurilor clasei. Prin urmare, la crearea obiectului, putem furniza valorile corespunzătoare pentru acești parametri:

Este de remarcat că în exemplul de mai sus, definirea câmpurilor clasei este redundantă. Referirea la câmpuri prin intermediul lui this în constructor va fi echivalentă cu definirea lor, și în acest caz putem să eliminăm definiția câmpurilor:

class Person{

   constructor(pName, pAge){
       this.name = pName;
       this.age = pAge;
   }
   print(){
       console.log(`Name: ${this.name}  Age: ${this.age}`);
   }
}
const tom = new Person("Tom", 37);
tom.print();    // Name: Tom  Age: 37
const bob = new Person("Bob", 41);
bob.print()     // Name: Bob  Age: 41

Expresii de clasă

JavaScript permite, de asemenea, definirea claselor prin intermediul expresiilor de clasă (class expression). Clasa este asignată unei variabile/constante, prin intermediul căreia se poate face referire la acea clasă ulterior:

const Person = class {
   constructor(pName, pAge){
       this.name = pName;
       this.age = pAge;
   }
   print(){
       console.log(`Name: ${this.name}  Age: ${this.age}`);
   }
}
const tom = new Person("Tom", 38);
tom.print();

Obținerea prototipului

La fel ca și funcția constructor, o clasă are un prototip, pe care îl poți obține folosind metodele standard:

class Person {

   constructor(pName, pAge) {
       this.name = pName;
       this.age = pAge;
   }

   print() {
       console.log(`Nume: ${this.name}  Vârstă: ${this.age}`);
   }
}

const tom = new Person("Tom", 37);

// obțineți prototipul
console.log(Person.prototype);                    // prin proprietatea prototype a clasei
console.log(tom.__proto__);                        // prin proprietatea __proto__ a obiectului
console.log(Object.getPrototypeOf(tom));           // prin funcția Object.getPrototypeOf și obiectul
console.log(tom.constructor);                       // obțineți funcția constructorului (tipul) obiectului