Nel mondo della programmazione moderna, uno dei concetti fondamentali è quello della programmazione orientata agli oggetti (OOP), e TypeScript si presenta come uno strumento essenziale in questo ambito. Essendo un superset di JavaScript, TypeScript porta con sé non solo i vantaggi del suo predecessore, ma anche una serie di funzionalità avanzate che rendono lo sviluppo di applicazioni più robusto e gestibile. Tra queste, le classi occupano un posto di rilievo, fungendo da pilastri per la creazione di strutture dati sofisticate e organizzate. In questo articolo, esploreremo in dettaglio le basi delle classi in TypeScript, analizzando la loro sintassi, le peculiarità e le potenzialità che offrono ai programmatori per costruire applicazioni scalabili e manutenibili.
Dalla definizione di una classe, passando per la comprensione dei costruttori, fino all'esplorazione di concetti come access modifiers e proprietà readonly, ci addentreremo nel cuore di TypeScript. Questa guida servirà sia per chi si avvicina per la prima volta a TypeScript, sia per chi, già familiare con JavaScript, desidera approfondire le sue conoscenze su come questo linguaggio estende e arricchisce le potenzialità dell'OOP.
Le classi in TypeScript
TypeScript, estendendo JavaScript, supporta la programmazione orientata agli oggetti tramite classi. Una classe in TypeScript è una sorta di blueprint per creare oggetti con caratteristiche e comportamenti specifici. È possibile definire proprietà (attributi) e metodi (funzioni) all'interno di una classe.
Definizione di una Classe
Una classe in TypeScript si definisce usando la parola chiave class
, seguita dal nome della classe. Ecco un esempio semplice:
1class Car {
2 brand: string;
3 model: string;
4
5 constructor(brand: string, model: string) {
6 this.brand = brand;
7 this.model = model;
8 }
9
10 displayDetails() {
11 console.log(`This car is a ${this.brand} ${this.model}.`);
12 }
13}
In questo esempio, abbiamo definito una classe Car
con due proprietà (brand
e model
) e un metodo (displayDetails()
).
Costruttore
Il costruttore è un metodo speciale che viene chiamato automaticamente quando si crea un'istanza della classe. Serve per inizializzare le proprietà della classe. Nel nostro esempio, il costruttore prende due parametri e li assegna alle proprietà dell'oggetto.
Creazione di un'istanza di una Classe
Per creare un oggetto basato su una classe, usiamo la parola chiave new
, seguita dal nome della classe e dai parametri richiesti dal costruttore:
1let myCar = new Car("Tesla", "Model S");
2myCar.displayDetails(); // Output: This car is a Tesla Model S.
Access Modifiers
Come accennato in precedenza, TypeScript supporta diversi modificatori di accesso: public
, private
, e protected
. Se non specificato, ogni membro di una classe è considerato public
.
public
: accessibile ovunque.private
: accessibile solo all'interno della classe.protected
: accessibile all'interno della classe e delle sue classi derivate.
Metodi
I metodi sono funzioni definite all'interno di una classe. Possono operare sui dati (proprietà) dell'oggetto e possono essere utilizzati per definire il comportamento degli oggetti della classe. Nel nostro esempio, displayDetails()
è un metodo.
Proprietà Readonly
TypeScript fornisce anche un modificatore readonly
, che impedisce la modifica di una proprietà dopo la sua inizializzazione.
1class Car {
2 readonly brand: string;
3
4 constructor(brand: string) {
5 this.brand = brand;
6 }
7}
8
9let myCar = new Car("Tesla");
10myCar.brand = "Audi"; // Errore: non è possibile assegnare a 'brand' perché è una proprietà di sola lettura.
Altre cose da tenere a mente sulle classi
- Proprietà Statiche e Metodi: Le classi possono avere proprietà e metodi statici. Questi appartengono alla classe stessa piuttosto che alle istanze della classe.
- Ereditarietà Multipla (tramite Mixins): TypeScript non supporta direttamente l'ereditarietà multipla, ma è possibile implementarla tramite i Mixins.
- Abstract Classes: Le classi astratte sono classi di base da cui possono derivare altre classi, ma non possono essere istanziate direttamente.
- Getter e Setter: TypeScript supporta getter e setter personalizzati per controllare l'accesso alle proprietà di una classe.
- Implementazione di Interfacce Multiple: Una classe può implementare più interfacce.
Ma cosa sono le interfacce?
Che cosa sono le interfacce in TypeScript?
Le interfacce in TypeScript sono un modo potente per definire contratti all'interno del tuo codice. Sono utilizzate per definire la struttura degli oggetti, assicurandosi che abbiano un determinato insieme di proprietà o metodi. Un'interfaccia può essere implementata da una classe, che deve poi fornire un'implementazione concreta per tutte le proprietà e i metodi definiti nell'interfaccia.
Definizione di un'Interfaccia
Una interfaccia in TypeScript si definisce con la parola chiave interface
. Ecco un esempio semplice:
1interface Person {
2 firstName: string;
3 lastName: string;
4 age?: number; // Proprietà opzionale
5
6 greet(): void; // Metodo
7}
In questo esempio, abbiamo definito un'interfaccia Person
con due proprietà obbligatorie (firstName
e lastName
), una proprietà opzionale (age
), e un metodo (greet
).
Implementazione di un'Interfaccia
Una classe può implementare un'interfaccia, significando che deve fornire un'implementazione per tutte le proprietà e i metodi definiti nell'interfaccia.
1class Employee implements Person {
2 firstName: string;
3 lastName: string;
4 age: number;
5
6 constructor(firstName: string, lastName: string, age: number) {
7 this.firstName = firstName;
8 this.lastName = lastName;
9 this.age = age;
10 }
11
12 greet() {
13 console.log(`Hello, my name is ${this.firstName} ${this.lastName}.`);
14 }
15}
16
17let employee = new Employee("John", "Doe", 30);
18employee.greet(); // Output: Hello, my name is John Doe.
Interfacce per Funzioni
Le interfacce possono anche essere utilizzate per definire la firma di una funzione. Questo è particolarmente utile quando si lavora con funzioni di callback o API che si aspettano una specifica forma di funzione.
1interface SearchFunc {
2 (source: string, subString: string): boolean;
3}
4
5let mySearch: SearchFunc;
6mySearch = function(source: string, subString: string) {
7 let result = source.search(subString);
8 return result > -1;
9}
Estensione delle Interfacce
Le interfacce possono estendere altre interfacce. Questo permette di comporre interfacce più complesse a partire da interfacce più semplici.
1interface Shape {
2 color: string;
3}
4
5interface Square extends Shape {
6 sideLength: number;
7}
8
9let square = <Square>{};
10square.color = "blue";
11square.sideLength = 10;
Altre cose da tenere a mente sulle interfacce
- Estensione di Multiple Interfacce: Un'interfaccia può estendere più di una interfaccia, consentendo la combinazione di più set di funzionalità.
- Interfacce per gli Array: È possibile definire un'interfaccia per un array dove si definisce il tipo di indice e il tipo di valore.
- Interfacce Ibride: Le interfacce in TypeScript possono essere ibride, cioè possono fungere sia da interfaccia per un oggetto che da funzione.
- Optional Properties and Readonly: Come accennato, le interfacce possono avere proprietà opzionali (
prop?: type
) e proprietà di sola lettura (readonly prop: type
). - Interfacce per la Duck Typing: TypeScript utilizza il duck typing (tipizzazione strutturale) per le interfacce. Questo significa che se due oggetti hanno la stessa forma, vengono considerati dello stesso tipo.
In sintesi, classi e interfacce in TypeScript offrono un'ampia gamma di funzionalità che possono essere sfruttate per costruire applicazioni robuste e ben strutturate. Questi concetti aggiuntivi forniscono una maggiore flessibilità e potenza nel definire e manipolare strutture di dati e comportamenti.
Caricamento...
Diventiamo amici di penna? ✒️
Iscriviti alla newsletter per ricevere una mail ogni paio di settimane con le ultime novità, gli ultimi approfondimenti e gli ultimi corsi gratuiti puubblicati. Ogni tanto potrei scrivere qualcosa di commerciale, ma solo se mi autorizzi, altrimenti non ti disturberò oltre.
Se non ti piace la newsletter ti ricordo la community su Discord, dove puoi chiedere aiuto, fare domande e condividere le tue esperienze (ma soprattutto scambiare due meme con me). Ti aspetto!