ES6 - Classi

Object Orientationè un paradigma di sviluppo software che segue la modellazione del mondo reale. Object Orientation, considera un programma come una raccolta di oggetti che comunica tra loro tramite meccanismo chiamatomethods. ES6 supporta anche questi componenti orientati agli oggetti.

Concetti di programmazione orientata agli oggetti

Per cominciare, cerchiamo di capire

  • Object- Un oggetto è una rappresentazione in tempo reale di qualsiasi entità. Secondo Grady Brooch, si dice che ogni oggetto abbia 3 caratteristiche:

    • State - Descritto dagli attributi di un oggetto.

    • Behavior - Descrive come agirà l'oggetto.

    • Identity - Un valore univoco che distingue un oggetto da un insieme di simili oggetti simili.

  • Class- Una classe in termini di OOP è un modello per la creazione di oggetti. Una classe incapsula i dati per l'oggetto.

  • Method - I metodi facilitano la comunicazione tra gli oggetti.

Traduciamo questi concetti orientati agli oggetti in quelli del mondo reale. Ad esempio: un'auto è un oggetto che contiene dati (marca, modello, numero di porte, numero del veicolo, ecc.) E funzionalità (accelera, cambia, apri le porte, accendi i fari, ecc.)

Prima di ES6, la creazione di una classe era una cosa complicata. Le classi possono essere create utilizzando la parola chiave class in ES6.

Le classi possono essere incluse nel codice dichiarandole o utilizzando espressioni di classe.

Sintassi: dichiarazione di una classe

class Class_name {  
}

Sintassi: espressioni di classe

var var_name = new Class_name {  
}

La parola chiave della classe è seguita dal nome della classe. Le regole per gli identificatori (già discusse) devono essere considerate durante la denominazione di una classe.

Una definizione di classe può includere quanto segue:

  • Constructors - Responsabile dell'allocazione della memoria per gli oggetti della classe.

  • Functions- Le funzioni rappresentano le azioni che un oggetto può intraprendere. A volte sono anche indicati come metodi.

Questi componenti messi insieme sono definiti come i membri di dati della classe.

Note - Il corpo di una classe può contenere solo metodi, ma non proprietà dei dati.

Esempio: dichiarazione di una classe

class Polygon { 
   constructor(height, width) { 
      this.height = height; 
      this.width = width; 
   } 
}

Esempio: espressione di classe

var Polygon = class { 
   constructor(height, width) { 
      this.height = height; 
      this.width = width; 
   } 
}

Lo snippet di codice precedente rappresenta un'espressione di classe senza nome. Un'espressione di classe denominata può essere scritta come.

var Polygon = class Polygon { 
   constructor(height, width) { 
      this.height = height; 
      this.width = width; 
   } 
}

Note - A differenza delle variabili e delle funzioni, le classi non possono essere sollevate.

Creazione di oggetti

Per creare un'istanza della classe, utilizzare la nuova parola chiave seguita dal nome della classe. Di seguito è riportata la sintassi per lo stesso.

var object_name= new class_name([ arguments ])

Dove,

  • La nuova parola chiave è responsabile dell'istanza.

  • Il lato destro dell'espressione richiama il costruttore. Al costruttore dovrebbero essere passati valori se è parametrizzato.

Esempio: creazione di un'istanza di una classe

var obj = new Polygon(10,12)

Accesso alle funzioni

È possibile accedere agli attributi e alle funzioni di una classe tramite l'oggetto. Utilizzare il '.'dot notation (chiamato come il punto) per accedere ai membri dei dati di una classe.

//accessing a function 
obj.function_name()

Esempio: metterli insieme

'use strict' 
class Polygon { 
   constructor(height, width) { 
      this.h = height; 
      this.w = width;
   } 
   test() { 
      console.log("The height of the polygon: ", this.h) 
      console.log("The width of the polygon: ",this. w) 
   } 
} 

//creating an instance  
var polyObj = new Polygon(10,20); 
polyObj.test();

L'esempio sopra riportato dichiara una classe "Polygon". Il costruttore della classe accetta due argomenti: rispettivamente altezza e larghezza. Il‘this’parola chiave si riferisce all'istanza corrente della classe. In altre parole, il costruttore sopra inizializza due variabili hew con i valori dei parametri passati al costruttore. Iltest () funzione nella classe, stampa i valori di altezza e larghezza.

Per rendere funzionale lo script, viene creato un oggetto della classe Polygon. L'oggetto è indicato dalpolyObjvariabile. La funzione viene quindi chiamata tramite questo oggetto.

Il seguente output viene visualizzato in caso di corretta esecuzione del codice precedente.

The height of the polygon:  10 
The width of the polygon:  20

Setter e Getters

Setter

Quando si tenta di impostare il valore di una proprietà, viene richiamata una funzione setter. Ilset keywordviene utilizzato per definire una funzione setter. La sintassi per definire una funzione setter è fornita di seguito:

{set prop(val) { . . . }}
{set [expression](val) { . . . }}

prop è il nome della proprietà da associare alla funzione data. val è un alias per la variabile che contiene il valore che si è tentato di assegnare alla proprietà. expression con ES6, può essere utilizzato come nome di una proprietà da associare alla funzione data.

Esempio

<script>
   class Student {
      constructor(rno,fname,lname){
         this.rno = rno
         this.fname = fname
         this.lname = lname
         console.log('inside constructor')
      }
      set rollno(newRollno){
         console.log("inside setter")
         this.rno = newRollno
      }
   }
   let s1 = new Student(101,'Sachin','Tendulkar')
   console.log(s1)
   //setter is called
   s1.rollno = 201
   console.log(s1)
</script>

L'esempio precedente definisce una classe Student con three properties vale a dire rno, fname and lname. Una funzione setterrollno() viene utilizzato per impostare il valore per la proprietà rno.

L'output del codice sopra sarà come mostrato di seguito -

inside constructor
Student {rno: 101, fname: "Sachin", lname: "Tendulkar"}
inside setter
Student {rno: 201, fname: "Sachin", lname: "Tendulkar"}

Esempio

L'esempio seguente mostra come utilizzare un file expression come nome di una proprietà con un setter function.

<script>
   let expr = 'name';
      let obj = {
      fname: 'Sachin',
      set [expr](v) { this.fname = v; }
   };
   console.log(obj.fname);
   obj.name = 'John';
   console.log(obj.fname);
</script>

L'output del codice sopra sarà come indicato di seguito -

Sachin
John

Getters

UN getter functionviene invocato quando si tenta di recuperare il valore di una proprietà. Ilget keywordviene utilizzato per definire una funzione getter. La sintassi per definire una funzione getter è fornita di seguito:

{get prop() { ... } }
{get [expression]() { ... } }

prop è il nome della proprietà da associare alla funzione data.

expression - A partire da ES6, puoi anche utilizzare le espressioni come nome di una proprietà da associare alla funzione data.

Esempio

<script>
   class Student {
      constructor(rno,fname,lname){
         this.rno = rno
         this.fname = fname
         this.lname = lname
         console.log('inside constructor')
      }
      get fullName(){
         console.log('inside getter')
         return this.fname + " - "+this.lname
      }
   }
   let s1 = new Student(101,'Sachin','Tendulkar')
   console.log(s1)
   //getter is called
   console.log(s1.fullName)
</script>

L'esempio sopra definisce una classe Student con tre proprietà, vale a dire rno, fname and lname. La funzione getterfullName() concatena il file fname e lname e restituisce una nuova stringa.

L'output del codice sopra sarà come indicato di seguito:

inside constructor
Student {rno: 101, fname: "Sachin", lname: "Tendulkar"}
inside getter
Sachin - Tendulkar

Esempio

L'esempio seguente mostra come utilizzare un'espressione come nome di proprietà con una funzione getter:

<script>
   let expr = 'name';
   let obj = {
      get [expr]() { return 'Sachin'; }
   };
   console.log(obj.name);
</script>

L'output del codice sopra sarà come indicato di seguito -

Sachin

La parola chiave statica

La parola chiave statica può essere applicata alle funzioni in una classe. I membri statici sono referenziati dal nome della classe.

Esempio

'use strict' 
class StaticMem { 
   static disp() { 
      console.log("Static Function called") 
   } 
} 
StaticMem.disp() //invoke the static metho

Note- Non è obbligatorio includere una definizione del costruttore. Ogni classe per impostazione predefinita ha un costruttore per impostazione predefinita.

Il seguente output viene visualizzato in caso di corretta esecuzione del codice precedente.

Static Function called

L'operatore instanceof

L'operatore instanceof restituisce true se l'oggetto appartiene al tipo specificato.

Esempio

'use strict' 
class Person{ } 
var obj = new Person() 
var isPerson = obj instanceof Person; 
console.log(" obj is an instance of Person " + isPerson);

Il seguente output viene visualizzato in caso di corretta esecuzione del codice precedente.

obj is an instance of Person True

Eredità di classe

ES6 supporta il concetto di Inheritance. L'ereditarietà è la capacità di un programma di creare nuove entità da un'entità esistente - qui una classe. La classe che viene estesa per creare classi più recenti è chiamataparent class/super class. Le classi appena create sono chiamatechild/sub classes.

Una classe eredita da un'altra classe utilizzando la parola chiave "extends". Le classi figlie ereditano tutte le proprietà e i metodi tranne i costruttori dalla classe genitore.

Di seguito è riportata la sintassi per lo stesso.

class child_class_name extends parent_class_name

Esempio: ereditarietà della classe

'use strict' 
class Shape { 
   constructor(a) { 
      this.Area = a
   } 
} 
class Circle extends Shape { 
   disp() { 
      console.log("Area of the circle:  "+this.Area) 
   } 
} 
var obj = new Circle(223); 
obj.disp()

L'esempio sopra dichiara una classe Shape. La classe è estesa dalla classe Circle. Poiché esiste una relazione di ereditarietà tra le classi, la classe figlia cioè la classe Circle ottiene un accesso implicito al suo attributo di classe genitore, cioè area.

Il seguente output viene visualizzato in caso di corretta esecuzione del codice precedente.

Area of Circle: 223

L'ereditarietà può essere classificata come:

  • Single - Ogni classe può estendersi al massimo da una classe genitore.

  • Multiple- Una classe può ereditare da più classi. ES6 non supporta l'ereditarietà multipla.

  • Multi-level - Considera il seguente esempio.

'use strict' 
class Root { 
   test() { 
      console.log("call from parent class") 
   } 
} 
class Child extends Root {} 
class Leaf extends Child   

//indirectly inherits from Root by virtue of inheritance {} 
var obj = new Leaf();
obj.test()

La classe Leaf deriva gli attributi dalle classi Root e Child in virtù dell'ereditarietà multilivello.

Il seguente output viene visualizzato in caso di corretta esecuzione del codice precedente.

call from parent class

Ereditarietà delle classi e sostituzione del metodo

Method Overridingè un meccanismo mediante il quale la classe figlia ridefinisce il metodo della superclasse. L'esempio seguente illustra lo stesso:

'use strict' ;
class PrinterClass { 
   doPrint() { 
      console.log("doPrint() from Parent called… ");
   }
}
class StringPrinter extends PrinterClass { 
   doPrint() { 
      console.log("doPrint() is printing a string…"); 
   } 
} 
var obj = new StringPrinter(); 
obj.doPrint();

Nell'esempio precedente, la classe figlia ha modificato l'implementazione della funzione della superclasse.

Il seguente output viene visualizzato in caso di corretta esecuzione del codice precedente.

doPrint() is printing a string…

La super parola chiave

ES6 consente a una classe figlia di richiamare il membro dati della classe padre. Ciò si ottiene utilizzando ilsuperparola chiave. La parola chiave super viene utilizzata per fare riferimento al genitore immediato di una classe.

Considera il seguente esempio:

'use strict' 
class PrinterClass { 
   doPrint() {
      console.log("doPrint() from Parent called…") 
   } 
}  
class StringPrinter extends PrinterClass { 
   doPrint() { 
      super.doPrint() 
      console.log("doPrint() is printing a string…") 
   } 
} 
var obj = new StringPrinter() 
obj.doPrint()

Il doPrint()ridefinizione nella classe StringWriter, emette una chiamata alla versione della sua classe genitore. In altre parole, la parola chiave super viene utilizzata per richiamare la definizione della funzione doPrint () nella classe genitore - PrinterClass.

Il seguente output viene visualizzato in caso di corretta esecuzione del codice precedente.

doPrint() from Parent called. 
doPrint() is printing a string.