La programmazione ad oggetti

Materie:Appunti
Categoria:Informatica

Voto:

1.3 (3)
Download:224
Data:15.02.2001
Numero di pagine:10
Formato di file:.doc (Microsoft Word)
Download   Anteprima
programmazione-ad-oggetti_1.zip (Dimensione: 10.68 Kb)
readme.txt     59 Bytes
trucheck.it_la-programmazione-ad-oggetti.doc     38 Kb


Testo

Perchè la programmazione ad oggetti?
L'attività del programmatore
Possiamo considerare l'attività del programmatore come quella di un ingegnere che costruisce un ponte. La cosa più importante e' che il ponte non crolli, ovvero che il programma funzioni. La programmazione a oggetti permette di costruire ponti che non crollano? Ahime no! Qualsiasi tecnica di costruzione programmi usiamo niente ci garantisce il successo del programma. Questo e' dovuto solo all'abilità del programmatore. Allora a cosa serve la programmazione ad oggetti? Bene, se siamo riusciti a costruire un programma funzionante in qualche modo, come seconda cosa importante , vorremmo che il programma sia di facile manutenzione. Infine vorremmo poterlo usare per costruire "altri ponti che non cadono". Ora la vecchia tecnica funzionale (programma =struttura di dati +funzioni) permette di costruire programmi "monolitici" di difficile manutenzione e riuso. La programmazione a oggetti invece spezzando il programma in tanti oggetti indipendenti dovrebbe facilitare queste operazioni. L'unica struttura di dati e libreria di funzioni del programma funzionale si e' trasformata in una serie di oggetti ognuno dei quali ha una propria struttura di dati e una libreria di funzioni. Come si vede un programma ad oggetti e' un'ulteriore astrazione del programma funzionale che potrebbe essere considerato come un programma a un solo oggetto. Per tornare alla nostra metafora ingegnieristica, ora stiamo costruendo ponti con moduli prefabbricati in modo da rendere più facile la costruzione di altri ponti simili.
I linguaggi ad oggetti: un'ulteriore astrazione Ora i dati sono racchiusi assieme alle funzioni negli oggetti: questa e' l'ulteriore astrazione introdotta dai linguaggi a oggetti. E, come vedremo, i dati sono accessibili solo attraverso speciali funzioni.
La struttura di dati che descrive lo stato di un oggetto viene definita ora dalle proprietà dell'oggetto e realizzata con le variabili dell'oggetto. (Queste sono chiamate talvolta anche campi fields in inglese). Mentre le funzioni che descrivono il comportamento dell'oggetto diventano i metodi dello stesso. La classe e' un pezzo di codice che descrive le proprieta' e i metodi di un oggetto. Per cui ora un programma e' formato da una serie di classi. Si dice anche che metodi e variabili sono membri della classe(in C++ infatti variabili e metodi si chiamano data members e member functions).
I linguaggi ad oggetto hanno particolari costrutti che permettono di trattare gli stessi oggetti.I n particolare l'operatore new permette di creare un oggetto descritto in una classe o come si dice di instanziare lo stesso o crearne una istanza. Questo corrisponde in pratica alla chiamata di un particolare metodo il costruttore che ha lo stesso nome della classe e che provvede a inizializzare la struttura di dati dell'oggetto(in effetti secondo i puristi il costruttore non e' un metodo ). L'accesso a una particolare proprietà o metodo di un oggetto avviene attraverso l'operatore ".":nomeoggetto.nomeproprieta e nomeoggetto.nomemetodo().I due riferimenti si distinguono solo per la presenza delle parentesi tonde per i metodi.
Un caso concreto
Volendo costruire un programma che tratti eventi della fisica delle alte energie con le loro tracce e i loro run, nel caso della programmazione funzionale costruiremmo una struttura di dati contenente Evento Traccia e Run più una libreria di funzioni che fanno diverse operazioni su questi dati. (Da notare che il nome funzione qui indica la stessa cosa di procedura, routine, sottoprogramma).
Nella programmazione a oggetti partiremmo subito dai 3 oggetti Traccia, Evento e Run e per ogni oggetto definiremmo quindi le proprietà e il comportamento. Le funzioni dell'approccio procedurale appaiono ora come metodi all'interno delle classi. Un programma utente ora invece di richiamare una serie di funzioni per manipolare i dati di una struttura, instanzia gli oggetti che servono e quindi chiede agli stessi oggetti di fare certe cose invocando i loro metodi.
Il modo di affrontare il problema e' cambiato completamente: mentre prima ragionavamo mettendoci nei panni del computer e definendo delle funzioni che dovevano portare alla soluzione, ora ragioniamo usando i termini del problema e definiamo degli oggetti che modellano il problema e ognuno dei quali ha particolari capacita' che permettono di risolvere il problema. Quindi non e' più il computer che disegna l'evento ma e' l'evento che disegna se stesso come se ogni oggetto fosse un piccolo computer specializzato.
Incapsulazione, Ereditarietà, Polimorfismo
Secondo i puristi, quanto detto finora , non basta per fare un linguaggio ad oggetti: sono necessarie inoltre le tre caratteristiche che adesso vedremo.
Chi usa un oggetto deve conoscere solo i nomi delle proprietà e dei metodi(ovvero la sua interfaccia) ma non ha bisogno di conoscere i dettagli dell'implementazione dello stesso che rimangono incapsulati, nascosti nello stesso: e' questa la cosiddetta incapsulazione dei linguaggi OO. Questa incapsulazione dovrebbe isolare il codice di un oggetto evitando che il suo cambiamento possa influenzare il codice di un altro oggetto e si realizza attraverso particolari attributi che proteggono l'accesso a classi, metodi e variabili che vogliamo rendere inaccessibili. In particolare incapsulazione significa proteggere le proprieta' rendendole accessibili solo attraverso speciali metodi di accesso (getValue) e di settaggio (setValue).
Se vogliamo modificare una classe non abbiamo bisogno di modificare la classe originaria(anche se potremmo farlo) come succedeva nella programmazione funzionale, ma i linguaggi a oggetti ci permettono di definire una nuova classe che estende o eredita l'altra classe aggiungendo nuovi metodi e proprieta' ed eventualmente ridefinendo (implementando)quelli della classe madre: e' questa l'ereditarieta' dei linguaggi OO.
Sfruttando questo meccanismo i programmi sono in effetti delle gerarchie di classi che condividono proprieta' e metodi: quando richiamiamo un metodo di un oggetto proveniente da una classe in questa gerarchia non stiamo richiamando un metodo ben definito, ma e' compito del linguaggio scoprire all'atto dell'esecuzione quale metodo andra' richiamato.Questo e' il polimorfismo dei linguaggi OO. Per questo non abbiamo per i linguaggi ad oggetto la fase di link, ma l'aggancio a nuove classi avviene in maniera dinamica all'atto dell'esecuzione. Questo particolare modo di lavorare permette di scrivere programmi che hanno messaggi "generici" come oggetto. disegna() che funzionano con diversi tipi di oggetti ed anche con oggetti che saranno definiti solo nel futuro.
Incapsulazione,ereditarieta' e polimorfismo sono le 3 principali proprieta' che definiscono i linguaggi OO.
In concreto
Tornando ora al nostro esempio degli eventi, se ora vogliamo aggiornare il codice, perche' si e' aggiunto un nuovo dato e dobbiamo modificare il sottoprogramma di disegno degli eventi in modo da utilizzare questo dato, nella programmazione ad oggetti questo non richiede alcuna modifica al codice originale. Viene solo aggiunta una nuova classe NuovoEvento aggiungendo le sole proprieta' e metodi modificati. Le applicazioni precedenti funzionano ancora perfettamente perche' il codice originario non e' stato cambiato.Inoltre ,se il nuovo codice ha solo ridefinito vecchi metodi, i vecchi programmi funzioneranno anche con i nuovi eventi senza cambiare una riga di codice.
Nella programmazione funzionale siamo costretti a modificare il codice precedente con possibili ripercussioni su tutte le applicazioni che gia' lo usavano.Intanto dobbiamo aggiungere un nuovo dato in tutte le procedure. Poi dovremo riscrivere tutte le procedure che usano il nuovo dato.
This,super e altri oggetti particolari
Nei linguaggi a oggetti le parole this e super hanno un significato speciale.This si riferisce al nome dell'oggetto del quale in questo momento stiamo eseguendo qualche metodo, super si riferisce invece alla classe madre di this.Infine in Java tutti gli oggetti sono discendenti da un'unica classe : la classe Object. Una sottoclasse viene creata con l'istruzione extends e può' ereditare da una sola superclasse. Cioe' in Java non abbiamo l'ereditarieta' multipla. La ridefinizione di un metodo si dice in gergo override mentre l'overload di un metodo si riferisce alla possibilità di avere più metodi con lo stesso nome ma con diverso numero e tipo di argomenti. In Java non possiamo invece sovraccaricare(overload in italiano) gli operatori come +. In Java tutto è oggetto eccetto gli ottotipi primitivi; percio' per poter operare su di essi(come oggetti) sono state create 8 classi Wrapper.
Classi Astratte e Interfacce: 2 classi molto speciali La classe progenitrice di tutte le altre e' spesso una abstract class della quale non si possono creare istanze e possiamo usarla solo estendendola.
Un'interfaccia(interface) e' anch'essa una classe astratta che contiene solo metodi non implementati. Tali metodi possono essere implementati da un'altra classe senza bisogno di estendere la classe ma implementando la stessa con l'istruzione implements.Una classe può estendere un'unica classe ma implementare un numero qualsiasi di interfacce. E' questa la maniera di Java di realizzare l'ereditarietà multipla.
Sia le classi astratte che le interfaccie permettono di descrivere delle interfaccie che saranno implementate estendendo le stesse. Ad esempio,in Java, per descrivere come deve essere scritto un oggetto che lavori nel browser si e' definita la classe astratta Applet. Chi vuole scrivere un programma che opera in una finestra di un documento Web estende questa classe implementandone i metodi come paint che indica cosa deve essere disegnato nella finestra.
Packages,strutture generate dall'ereditarietà e strutture di dati
Nella programmazione ad oggetti e' facile confondersi se non si capisce bene la differenza tra classi e oggetti e tra strutture formate da classi e strutture formate da oggetti. Inoltre abbiamo strutture presenti solo sul programma scritto e strutture che si creano all'atto dell'esecuzione del programma. Gli oggetti, ad esempio, esistono solo all'atto dell'esecuzione a differenza della classe che e' presente sia nel programma scritto che all'atto dell'esecuzione sotto forma di variabili e metodi di classe. Queste variabili e questi metodi vengono detti in Java statici perche' realizzati attraverso la parola chiave static. Per cui all'atto dell'esecuzione, per ogni classe usata, avremo le variabili e i metodi statici sempre presenti piu' un numero variabile(anche 0) di oggetti istanziati. Ogni oggetto istanziato ha le proprie variabili e i vari oggetti attraverso queste variabili possono puntare l'uno all'altro creando una struttura di dati:ad esempio una lista. Viceversa le classi,oltre ad essere organizzate nella loro struttura gerarchica di ereditarieta' (che ha come effetto all'atto dell'esecuzione che tutte le classi madri di una classe usata sono caricate) sono raggruppate anche in packages(pacchetti). La divisione in packages non ha niente a che fare con l'ereditarieta' e viene introdotta per questioni di comodita'. Le classi di uno stesso package hanno un'accesso facilitato alle proprie variabili e e ai propri metodi. Questo e' utile per facilitare la scrittura di classi di servizio che servono solo a realizzare la funzionalita' presente nelle classi pubbliche del package.Tutte le classi di un package dividono la stessa cartella che di solito ha lo stesso nome del package.Queste cartelle possono formare una struttura gerarchica che non ha nessun particolare significato.Invece il singolo file,in Java,contiene una sola classe pubblica e un numero qualsiasi di classi di servizio e puo' quindi essere considerato come un minipackage.
Il livello di accesso di una classe,variabile o metodo e' definito in Java tenendo conto di queste strutture.Questo va infatti da private(accesso consentito nella sola classe) a livello di default (accesso consentito nel pacchetto), a protected accesso consentito alle classi nel pacchetto e alle classi figlie in altri pacchetti; a public accesso generalizzato.
Persistenza degli oggetti
La programmazione ad oggetti,mettendo l'accento sugli oggetti, cambia completamente il modo di considerare l'input/output. Prima si era portati a considerare le strutture di dati in memoria come separate e diverse dalle strutture di dati sulle memorie di massa, con istruzioni di I/O che leggendo da nastro o disco popolano le strutture di dati in memoria.In un linguaggio ad oggetti questo modo di porre il problema e' (o dovrebbe essere) obsoleto: abbiamo solo oggetti persistenti (cioe' con una copia su memoria di massa) che vengono copiati,quando servono, tali e quali e poi eventualmente riscritti se cambiano di stato. Percio' in un linguaggio ad oggetti invece di parlare di I/O si parla di persistenza degli oggetti. Solo alcuni degli oggetti di un programma saranno persistenti, mentre la maggioranza sara' del tipo transiente che viene distrutto quando il programma termina l'esecuzione.Java permette di leggere e scrivere oggetti realizzando la persistenza ma una soluzione definitiva di questo problema si avra' solo con l'affermarsi dei data base ad oggetti in contrapposizione ai data base relazionali ora piu' in auge.
In definitiva ...
La classe incapsula certi dati e i metodi per accedervi.Mentre prima chiunque poteva modificare quei dati, ora dovete farlo passando attraverso la classe e questo evita un sacco di problemi.
Un programma e' un insieme di oggetti che comunicano tra di loro mandandosi dei messaggi. Questi messaggi, consistenti nella chiamata di un metodo, chiedono all'oggetto che riceve il messaggio di fare qualcosa.
Potete pensare a un oggetto come un tipo di dati più complesso che si aggiunge agli 8 tipi primitivi di dati. A questi dati puoi richiedere di fare certe operazioni su se stessi, richiamando dei metodi.
Ogni oggetto ha una sua propria memoria che può contenere dati primitivi e altri oggetti. Questo permette di creare degli oggetti di grande complessità' partendo da oggetti semplici e impacchettandoli in un nuovo oggetto.
In un programma a oggetti potete inviare dei messaggi generici, a cui ogni oggetto risponderà a seconda della sua posizione nella gerarchia delle classi.
L'idea di fondo e' di far scrivere ai migliori programmatori degli oggetti che poi possano essere riusati da tutti per costruire nuove applicazioni.
Java, con le sue librerie specializzate, fornisce migliaia di questi oggetti pronti per l'uso. Questo ,non solo per facilitare il lavoro dei programmatori, ma anche per fornire un ambiente di lavoro identico su tutte le piattaforme su cui Java gira.Imparare a programmare in Java significa innanzitutto conoscere queste librerie di classi.
Java Development Kit : JDK
Per programmare in Java occorre procurarsi il JDK della Sun (Java Development Kit) che e' la distribuzione ufficiale in una delle sue varie versioni. Java viene fornito come una libreria di classi suddivise in packages e compresse nel formato zip più una serie di programmi eseguibili. Talvolta questo e' già disponibile sul computer che usate.Per scoprirlo e sapere quale versione e' disponibile basta dare il comando(da finestra MSDos su PC):
java -version
Applicazione 1:Il piu' semplice programma Java
class Ciao{
public static void main (String args[]){
System.out.println("Ciao a tutti");
}
}
Per scrivere programmi Java usate un editore di testi come Wordpad su Pc o vi su Unix.Copiate il programma e salvatelo in un file di nome Ciao.java L'istruzione
javac Ciao.java
compilera' il programma' creando un file: Ciao.class Finalmente l'istruzione
java Ciao
fara' eseguire il programma che scrivera' la frase Ciao a Tutti.
Applet 2:Il piu' semplice applet
Un applet e' un programma Java che gira all'interno di un browser.
import java.awt.*;
import java.applet.*;
public class Ciao extends Applet {
public void paint(Graphics g){
g.drawString("CiaoATutti",5,25);
}
}
Salvatelo su disco in un file Ciao.java come avete fatto con l'altro programma e poi compilatelo col solito comando:
javac Ciao.java
Questo crea il compilato Ciao.class. Per poterne vedere l'esecuzione dovete inserire il programma Java in una pagina Web. Questo si fa scrivendo un documento HTML con l'istruzione:
che va salvato su disco col nome Ciao.html nella stessa cartella del programma Java. Ora basta leggere il documento col browser per poter vedere il programma in esecuzione. (Se fate queste operazioni su una cartella visibile dal Web e volete accedere all'applet con una URL dovete probabilmente sproteggere i file ciao.htm e ciao.class: su macchine Unix usate il comando
chmod 644 nomefile
Ma in fase di costruzione di un applet e' molto piu' comodo usare uno speciale programma del jdk chiamato appletviewer:questo lo si usa col comando
appletviewer Ciao.html
Cercate di familiarizzarvi con questa procedura che sara' usata in tutto il corso.

Esempio