Classe (informatica)
Una classe, nella programmazione orientata agli oggetti, è un costrutto di un linguaggio di programmazione usato come modello per creare oggetti. Tale modello comprende attributi e metodi che saranno condivisi da tutti gli oggetti creati (istanze) a partire dalla classe. Un oggetto è, di fatto, l'istanza di una classe.
Una classe è identificabile come un tipo di dato astratto che può rappresentare una persona, un luogo oppure una cosa, ed è quindi l'astrazione di un concetto, implementata in un software. Fondamentalmente, essa definisce al proprio interno lo stato, i cui dati sono memorizzati nelle cosiddette variabili membro o attributi, e il comportamento dell'entità di cui è rappresentazione, descritto da blocchi di codice riutilizzabili chiamati metodi.
Descrizione
modificaNell'analisi object-oriented
modificaIl termine classe può indicare, a seconda del contesto, una categoria di oggetti, un tipo di dati, o l'implementazione di un tipo di dati. Queste tre accezioni si trovano rispettivamente (soprattutto) nell'analisi orientata agli oggetti, nella progettazione orientata agli oggetti e nei linguaggi di programmazione orientati agli oggetti.
L'analisi dei requisiti, o semplicemente analisi, costituisce una delle prime fasi del ciclo di vita del software, e precede almeno le fasi di progettazione e implementazione. Lo scopo di questa fase è comprendere, chiarire e documentare cosa il sistema software deve fare, ovvero quali sono le funzionalità che si richiede possieda; non ci si occupa invece di definire come siano realizzate queste funzionalità (se non, a un livello molto grossolano, per una stima approssimativa dei costi).
Si parla di analisi object-oriented se tale fase viene condotta utilizzando tecniche che si basano su un metamodello object-oriented ovvero, detto più semplicemente, se l'analisi fa uso degli strumenti concettuali propri delle tecnologie orientate agli oggetti, primo fra tutti il concetto di "classe".
Nell'analisi object-oriented si possono distinguere due sotto-attività: l'analisi del dominio e l'analisi dei requisiti propriamente detta. L'analisi del dominio consiste nel chiarire innanzitutto quali sono i concetti importanti che il sistema da sviluppare dovrà trattare, e nel precisare il più dettagliatamente possibile il significato di questi concetti e le relazioni che li legano l'uno all'altro.
Per esempio, durante la fase di analisi per un sistema software nel dominio bancario occorrerà investigare a fondo come funziona un conto corrente, quali relazioni possono legare diversi conti, i conti alle filiali, le filiali ai clienti, e così via. Successivamente alla caratterizzazione precisa delle entità facenti parte del dominio si procederà a stendere i requisiti veri e propri del sistema, ovvero descrivere come il sistema si inserisce nel dominio e interagisce con esso.
Nell'analisi object-oriented la classe è il concetto fondamentale utilizzato per descrivere le entità del dominio. Una classe rappresenta una categoria di entità (per esempio, i conti correnti) in termini di due aspetti:
- lo stato delle entità di quella categoria, descritto in termini di un insieme di attributi che possono variare nel tempo; per esempio, ogni conto corrente ha un saldo che varia nel tempo;
- il comportamento di quelle entità, in termini delle operazioni che tali entità possono eseguire o che possono essere eseguite su di esse; per esempio, da un conto corrente si può prelevare denaro. Le operazioni vengono analizzate stabilendo (anche) in quale modo la loro applicazione modifica lo stato (il prelievo di denaro diminuisce l'entità del saldo).
Le singole entità vengono dette istanze (ovvero esempi, casi particolari) della loro classe di appartenenza. Così, il mio conto corrente è un'istanza della classe conto corrente.
Il modello del dominio che l'analisi va a definire può essere arricchito da una serie di informazioni aggiuntive che riguardano le relazioni fra le diverse classi identificate. Fra gli esempi solitamente più importanti di relazione si possono citare i seguenti:
- le associazioni specificano relazioni fra le istanze delle classi; per esempio, il fatto che i conti correnti siano intestati a clienti della banca definisce un'associazione fra la classe conto corrente e la classe cliente;
- le aggregazioni sono un tipo particolare di associazione che ha luogo quando le istanze di una classe devono considerarsi parti di istanze di altre classi; per esempio, un'istanza della classe automobile comprende come proprie parti istanze delle classi ruota, pistone, parabrezza e via dicendo. Il confine fra associazioni generiche e aggregazioni non è sempre netto.
- le relazioni ISA (relazione "è un") specificano che una classe deve considerarsi una sottocategoria o sottoclasse di un'altra (detta superclasse); per esempio, la classe conto corrente potrebbe essere descritta come sottocategoria della classe servizio bancario. Il nome della relazione segue dal fatto che si può sensatamente dire, per esempio, che un conto corrente è un ("is a", ISA) servizio bancario. Si noti che questa rappresenta una relazione esclusivamente fra classi e non fra istanze. La relazione ISA ha un ruolo importante nella razionalizzazione di un modello. Un aspetto fondamentale è che si può assumere che una sottoclasse sia sicuramente dotata di tutti gli attributi, le operazioni e le associazioni della superclasse; eventualmente può averne altre, legate alle particolarità specifiche della sottocategoria di oggetti che descrive. Per esempio, se un servizio bancario ha un costo annuo ed è intestato a un cliente, tutto ciò resta vero per un conto corrente; quest'ultimo ha inoltre un saldo, attributo che non ha necessariamente senso per tutti i servizi bancari (e che quindi non comparirà nella classe più generica servizio bancario).
Nella progettazione object-oriented
modificaLa progettazione è una fase del ciclo di vita del software concettualmente successiva all'analisi del dominio e all'analisi dei requisiti, in cui ci si pone il problema di come realizzare un sistema software che risponda ai requisiti precedentemente esplicitati. Il risultato di questa fase dovrebbe essere un insieme di specifiche di progetto sufficientemente dettagliate e precise da poter essere utilizzate come unico riferimento per la successiva fase di implementazione, cioè per la costruzione del prodotto software vero e proprio.
La progettazione orientata agli oggetti viene generalmente utilizzata nei casi in cui si prevede una implementazione anch'essa orientata agli oggetti, in un linguaggio opportuno come C++ o Java. Questi linguaggi dispongono infatti di un concetto di classe (vedi sezione successiva) strutturalmente simile a quello utilizzato in fase di analisi. In tal caso, la progettazione consiste in un raffinamento e una estensione del modello prodotto dall'analisi. Questa trasformazione del modello avviene sulla base di due linee guida generali:
- si identificano tutti i concetti nuovi legati all'architettura del sistema, ovvero che hanno a che vedere con il modo in cui il sistema dovrà essere realizzato ma che non corrispondono a concetti del dominio. Concetti di questo tipo potrebbero essere terminale, utente abilitato, indirizzo IP, base dati e così via. Tutti questi concetti non sono afferenti al dominio, ma esclusivamente al sistema, e tuttavia si prestano a essere descritti ancora attraverso il concetto di classe.
- le classi del modello risultante (sia quelle derivati dall'analisi che quelle legate all'architettura del sistema) vengono solitamente dettagliate introducendo informazioni aggiuntive che serviranno a guidare l'implementazione; per esempio, si stabiliscono i tipi degli attributi e dei parametri delle operazioni. Si potrà stabilire, per esempio, che il saldo di un conto corrente sia un numero con la virgola, e analogamente l'operazione "preleva" richieda la specifica di un numero con la virgola che rappresenta la somma da prelevare.
Si può dire che in questa fase il sistema viene descritto in termini di tipi di dati astratti.
Nei linguaggi object-oriented
modificaUna delle caratteristiche fondamentali dell'approccio orientato agli oggetti è la maggiore "fluidità" (rispetto agli approcci precedenti, come quello procedurale) con cui le fasi di analisi, progettazione e implementazione sfociano ciascuna nella successiva. Questa fluidità è dovuta al fatto che i linguaggi orientati agli oggetti forniscono una serie di strumenti sintattici e semantici che sono la diretta trasposizione degli strumenti concettuali di cui si è parlato per quanto riguarda le fasi di analisi e progettazione.
Un linguaggio orientato agli oggetti fornisce un costrutto di classe strutturalmente corrispondente al concetto astratto di classe menzionato sopra: una classe descrive un tipo di oggetti (~ una categoria di entità) in termini di un insieme di variabili interne o variabili d'istanza di cui tali oggetti sono dotati (~ attributi) e un insieme di procedure dette metodi che possono essere eseguite su di essi (~ operazioni). Una variabile interna di una classe che contenga un riferimento a un'istanza di un'altra classe può corrispondere a un'associazione; una variabile interna che contenga direttamente un'istanza vera e propria può considerarsi trasposizione implementativa del concetto di aggregazione; e infine l'ereditarietà corrisponde direttamente alla relazione ISA.
Se da un punto di vista storico e tecnico la classe dei linguaggi orientati agli oggetti si può considerare come una evoluzione del record di linguaggi procedurali tipo C o Pascal, essa sottende un approccio completamente diverso alla programmazione, in cui i tipi di dati, corredati delle loro operazioni (metodi) diventano centrali. Gran parte delle novità significative di questo approccio sono legate ai concetti di ereditarietà, incapsulamento (o information hiding) e polimorfismo.
Nell'UML
modificaUML è una notazione grafica semi-formale che consente di descrivere un sistema (non necessariamente software) creandone un modello basato sui concetti propri dell'orientamento agli oggetti. Poiché tutte le fasi del ciclo di vita del software orientato agli oggetti utilizzano strumenti concettuali analoghi (classi, associazioni, relazioni ISA), UML può essere usato in modo omogeneo in tutte le fasi. La conseguente uniformità di descrizione ha una serie di vantaggi:
- maggiore facilità della verifica della rispondenza di ciascuna fase ai vincoli imposti dalla precedente (per esempio, verifica che l'implementazione sia coerente con i requisiti);
- maggiore modificabilità dell'insieme dei modelli prodotti; per esempio, da una modifica al modello dell'analisi (dovuto a un cambiamento di requisiti) è spesso semplice (o addirittura banale) ricavare quali modifiche debbano di conseguenza essere apportate al modello della progettazione e quindi all'implementazione.
Proprio perché le classi sono fra gli strumenti centrali che consentono di porre in relazione modelli di analisi, modelli di progetto, e implementazioni software, il concetto di classe in UML ha una semantica più astratta e concettuale o generale di quanto non avvenga nei linguaggi di programmazione.
Esempi
modificaUn esempio generico di codice sorgente di una classe in Java è:
//definizione, corpo o template della classe
public class <nome_classe> {
//attributi o membri della classe
tipo_attributo1 <attributo1>;
...
tipo_attributoN <attributoN>;
//costruttore di default (senza parametri)
public <nome_classe_maiuscolo> (){
}
//costruttore con parametri
public <nome_classe_maiuscolo> (tipo_parametro1 param1, ... , tipo_parametroN paramN){
<attributo1>=param1;
...
<attributoN>=paramN;
}
//metodo membro
public tipo_ritorno <nome_Metodo> (tipo_parametro1 param1, ... , tipo_parametroN paramN){
...
''blocco_istruzioni'';
...
return <oggetto_tipo_metodo>;
}
//metodo non membro (statico)
public static tipo_ritorno <nome_Metodo> (tipo_parametro1 param1, ... , tipo_parametroN paramN){
...
''blocco_istruzioni'';
...
return <oggetto_tipo_metodo>;
}
//entry point del programma o metodo di esecuzione
public static void main (String [] args){
...
\\istanzia oggetto della classe
<nome_classe> pippo=new <nome_classe>();
\\chiama costruttore per assegnare valori ad attributi dell'oggetto
pippo.<costruttore>(parametri_passati);
\\chiama o invoca metodo membro sull'oggetto
pippo.<nome_metodo>(parametri_passati);
...
\\chiama o invoca metodo statico
<nome_metodo_statico>(parametri_passati);
...
}
}
Un esempio generico di codice sorgente di una classe in C# è:
public class <nome_classe>
{
// Attributi o membri della classe
tipo_attributo1 <attributo1>;
...
tipo_attributoN <attributoN>;
// Costruttore di default ovvero senza parametri
public <nome_classe> ()
{
}
// Costruttore con parametri
public <nome_classe> (tipo_param1 param1, ... , tipo_paramN paramN)
{
<attributo1> = param1;
...
<attributoN> = paramN;
}
// Metodo membro
public tipo_ritornato <nome_Metodo> (tipo_param1 param1, ... , tipo_paramN paramN)
{
// Logica del metodo
...
// Ritorno
return <oggetto_tipo_metodo>;
}
// Metodo statico
public static tipo_ritornato <nome_Metodo> (tipo_param1 param1, ... , tipo_paramN paramN)
{
// Logica del metodo
...
// Ritorno
return <oggetto_tipo_metodo>;
}
// Entry point del programma o metodo di esecuzione
public static void main (String [] args)
{
// Istanzia oggetto della classe
<nome_classe> nome_oggetto = new <nome_classe>(eventuali_param);
// Chiama un metodo membro dell'oggetto
nome_oggetto.<nome_metodo>(eventuali_param);
// Chiama un metodo statico dell'oggetto
nome_oggetto.<nome_metodo_statico>(eventuali_param);
}
}
Voci correlate
modificaAltri progetti
modifica- Wikizionario contiene il lemma di dizionario «classe»
Collegamenti esterni
modifica- (EN) Denis Howe, class, in Free On-line Dictionary of Computing. Disponibile con licenza GFDL