Valuta la risposta

 


Cerca in vialattea.net
 

Vuoi che ti siano segnalate le nuove risposte di chiedi all'esperto ?
Scrivi qui sotto il tuo indirizzo e-mail e invia!

10-06-2001

Condividi    versione stampabile    

Cosa sono e cosa servono le classi super e l'ereditarietà? E' possibile avere un paio di esercizi sulla programmazione concorrente in java con l'uso di semafori?

(Risponde Valerio Cecere)

Innanzitutto non esistono classi super, in Java si usa la parola super per indicare la classe da cui deriva quella che stiamo scrivendo. Mentre l'ereditarietà è uno dei concetti fondamentali della programmazione ad oggetti. Quando si decide di adottare questa metodologia, si dovrebbero seguire determinati passaggi. La prima cosa da fare è l'analisi del problema per trovare una soluzione. Una volta trovata, si rivede tutto il processo risolutivo, cercando di individuare le entità fondamentali che intervengono nel raggiungimento della soluzione. Inoltre è necessario capire con esattezza come interagiscono tra di loro queste entità.
Quando si termina questa analisi spesso ci si accorge che molte di queste entità o oggetti appartengono a delle categorie o classi che li raggruppano a uno o più livelli determinando una gerarchia di classi, e proprio l'ereditarietà permette lo sfruttamento delle capacità delle classi genitrici per lo sviluppo di sottoclassi specializzate per un compito ben preciso.
Pensiamo ad una classe per la gestione di un serbatoio, questa classe avrà una variabile interna che indicherà la quantità di liquido contenuto al suo interno, e una lo stato del rubinetto che permette di riempirlo o svuotarlo. Supponiamo di voler gestire un tipo particolare di serbatoio in cui è di fondamentale importanza anche la temperatura e la pressione del contenuto. Senza l'ereditarietà avremmo dovuto duplicare il codice scritto per il primo tipo di serbatoio, e modificarlo per tenere conto delle nuove esigenze.
A un certo punto ci accorgiamo che per tutti i serbatoi dovremmo gestire un'altra informazione, per esempio quante volte è stato usato, magari per determinare un indice di usura, superato il quale andrebbe verificato lo stato generale del serbatoio.
Avendo duplicato il codice dovremo modificare entrambi le classi per i due tipi di serbatoi. E in fin dei conti siamo stati fortunati che esistessero solo due tipi di serbatoi, nel caso ce ne fossero stati di più avremmo dovuto fare un lavoro molto maggiore, con un notevole aumento della probabilità di introdurre un errore da qualche parte.
Per aggirare il problema ci viene in aiuto l'ereditarietà, con cui avremmo definito il secondo serbatoio come un derivato dal primo, e questo ci avrebbe evitato la duplicazione del codice e nel momento dell'introduzione della gestione dell'indice di usura, la modifica l'avremmo apportata solo alla prima classe e sarebbe stata ereditata da tutte le classi derivate. Il nostro lavoro sarebbe stato molto minore e la possibilità di introdurre errori sarebbe stata minima.
In Java avremmo scritto qualcosa del genere in cui si può vedere l'uso della parola chiave super.

class Serbatoio {
private double capacita=100.0;
private double contenuto=0.0;
private bool rubinetto=false; // Variabile a true -> aperto

private int usura=0; // Variabile aggiunta per l'indice di usura

public bool apri()
{
if(rubinetto==false) {
rubinetto=true;
usura++;
}
}

public bool pericolo()
{
return usura>1000;
}


// Altri metodi di interfaccia
...
}

class SerbatoioPressurizzato extends Serbatoio {
private double temperatura;
private double pressione;

public bool pericolo()
{
return super.pericolo() // L'uso di super è fondamentale, senza si avrebbe
// una chiamata ricorsiva infinita.
|| temperatura>35.0
|| pressione>5;
}


// Altri metodi di interfaccia
...
}

Oltre a questi vantaggi l'ereditarietà permette la gestione e riutilizzo di codice arbitrariamente complesso e di cui potremmo benissimo non sapere nulla dei suoi processi interni. In realtà questo è possibile anche con una programmazione non ad oggetti e quindi senza ereditarietà, ma non in modo tanto pulito e trasparente.

Passiamo ora alla programmazione concorrente. Bisogna premettere che in java la programmazione concorrente ha delle restrizioni imposte dall'essere un linguaggio indipendente dal sistema operativo. Per cui parlare di semafori è o altri metodi classici per gestire l'esecuzione concorrente di processi è delicato. Iniziamo col dire che esistono due tipi di sincronizzazione, quella tra processi distinti e quella all'interno di uno stesso processo tra i suoi diversi thread. Tra processi la sincronizzazione può avvenire solo se si dispone di meccanismi offerti dal sistema operativo per farli comunicare. Tra questi possiamo ricordare i messaggi, i socket, la memoria condivisa, le pipe, i semafori, o il semplice l'accesso esclusivo ad un file. Di questi solo i semafori sono stati pensati appositamente per la sincronizzazione, ma con le altre forme di comunicazione è possibile implementare in modo piu o meno macchinoso sistemi equivalenti, magari con la definizione di un processo server che offra semafori ai client e quindi con l'uso di una comunicazione come i socket. In effetti le uniche IPC (Inter Process Comunication) previste da Java sono i file, e i socket che quindi devono essere supportati dal sistema operativo. Mentre per la sincronizzazione dei thread, e quindi all'interno di uno stesso processo, la comunicazione non è un problema, perché tutti i thread di un processo condividono la stessa area di memoria, per cui "vedono" tutti gli stessi dati. Anche in questo caso Java non fornisce oggetti per la sincronizzazione, perché è stata inserita nel linguaggio una parola chiave per non permettere l'esecuzione di una parte di codice da più thread contemporaneamente. Il termine in questione è synchronized che inserito tra i modificatori di un metodo lo rende thread-safe, ma è possibile usarlo per la definizione di una sezione critica, che concettualmente è simile al metodo sincronizzato, ma si riferisce solo ad una porzione di codice. Il funzionamento di synchronized è molto interessante, e sinceramente ho scoperto alcuni particolari proprio scrivendo questo esempio. Infatti la prima stesura non funzionava, mentre la seconda che apparentemente è uguale, funziona perfettamente rivelando un particolare molto importante.

Esercizio: Thread in competizione.

 

 

 

Ti è piaciuta questa risposta? Ti è risultata utile?
Se si, ti invitiamo a sostenere "Chiedi all'esperto" con una piccola donazione, che servirà a coprire le spese di gestione del sito.

 

 
   © 1997-2012 - vialattea.net - Tutti i diritti riservati
Credits | Libro degli ospiti | Privacy | Area esperti