La programmazione ad oggetti oop (Object Oriented)



Scaricare 35.75 Kb.
24.01.2018
Dimensione del file35.75 Kb.

LA PROGRAMMAZIONE AD OGGETTI OOP (Object Oriented)
Appunti sulla OOP per gli studenti, solo per uso scolastico.
La OOP è un paradigma di programmazione che tende a creare delle unità indipendenti dotate di vita propria, alla base di questa tecnologia di programmazione vi sono pochi semplici concetti di immediata applicabilità.

I due concetti base sono quello di OGGETTO e di CLASSE:

OGGETTO: qualsiasi cosa, sia fisica oppure concettualmente definita, che si possa trovare nel mondo circostante. L’oggetto è una entità completa, che contiene (incapsula) sia le informazioni che ne descrivono lo stato, sia le procedure che operano facendo uso delle informazioni stesse modificandone lo stato. L’oggetto comunica con il modo esterno mediante un’interfaccia pubblica ed è una scatola nera, nasconde verso l’esterno la sua implementazione fisica.

CLASSE: schema descrittivo ad alto livello di oggetti reali. La classe traccia le caratteristiche fisiche di un oggetto generico mediante la definizione di attributi, azioni e interfaccia esterna.


Le classi sono in pratica una famiglia di oggetti, potremo ad esempio individuare la classe Fiori, dove gli oggetti sono i singoli fiori. Le classi, quindi, permettono il raggruppamento di oggetti che devono condividere lo stesso comportamento.

Nella programmazione le classi forniscono lo schema da cui è possibile creare un oggetto (istanziazione), infatti si dice che un oggetto è un’istanza della classe e ne assume tutte le caratteristiche. Per ogni classe possiamo individuare e definire le proprietà o caratteristiche degli oggetti istanziati:

ATTRIBUTI: variabili che caratterizzano il suo stato

METODI: procedure che permettono di accedere all'oggetto modificandolo o visualizzando il valore delle sue caratteristiche


O
gni volta che dobbiamo definire una classe si devono individuare gli attributi e i metodi. Supponiamo di voler realizzare una classe veicolo terrestre e assumiamone la seguente definizione: “qualsiasi mezzo di trasporto, per persone o cose, specificatamente meccanico e guidato dall’uomo”. L'analisi ha lo scopo di illustrare i concetti fondamentali che sono alla base della OOP e non parte da uno specifico problema che si vuole risolvere. Va detto che a seconda dell'applicazione specifica sarà necessario dettagliare alcune caratteristiche piuttosto che altre, oppure sviluppare l'analisi con molta accuratezza in modo da rendere tali classi utilizzabili nella globalità delle situazioni particolari. Non avendo la pretesa della completezza, quanto segue è da considerarsi soprattutto come un esempio di schema di ragionamento nel quale gli attributi individuati non sono gli unici possibili e nulla vieta che possano esserne trovati altri diversi dai precedenti.
Prima ancora di elencare i possibili elementi appartenenti alla classe si possono individuare alcune caratteristiche che sono comuni nel senso che, pur potendo essere diverse tra un veicolo e l'altro, caratterizzano tutti gli oggetti che stiamo considerando:

  • la dimensione;

  • la velocità attuale;

  • il numero di ruote;

  • cosa trasportano;

  • il tipo di propulsione.

Per dimensione si intende lunghezza, larghezza, altezza; così come per velocità attuale si intende la velocità istantanea del veicolo: sarà più chiaro il ruolo che assume questo parametro successivamente quando si andranno a descrivere le operazioni possibili sulla classe di oggetti che stiamo definendo.

Poiché i veicoli terrestri sono generalmente dotati di ruote, che variano se si prende una bicicletta o un camion, potremo prendere come attributo il numero di ruote; inoltre tutti i veicoli trasportano persone o cose o entrambi e quindi tra gli attributi significativi vi sarà l'indicazione di cosa trasportano. L'ultima caratteristica comune è stata individuata nel tipo di propulsione che consente ai veicoli il movimento. Questa potrà poi essere di tipo animale, ogni volta che l'uomo o un animale trainano il veicolo (avremo per esempio la bicicletta o un carro), di tipo chimico, se il veicolo ha un motore come nelle usuali automobili.

In sostanza se si vuole definire la classe astratta VeicoloTerrestre questa dovrà contenere come campi tutti gli elementi che vengono considerati caratteristici dei reali oggetti veicolo con cui si intende lavorare; la classe esprime l'idea di veicolo e racchiude le proprietà che appartengono alla generalità di essi; i singoli oggetti potranno poi distinguersi l'uno dall'altro, in quanto l'uno o l'altro dei parametri indicati può assumere un valore particolare. All'atto del disegno di una classe veicolo si potrà ipotizzare la seguente struttura:

In essa gli attributi individuati sono quelli discussi sopra, mentre relativamente alla voce Metodi verranno discussi in seguito.


CLASSI DERIVATE


L'analisi ha isolato le sole proprietà comuni alla generalità dei veicoli e quindi va ulteriormente approfondita. Una scelta può essere quella di suddividerli tenendo conto per esempio che taluni hanno il motore e altri no.


E’ stato possibile quindi individuare sottoclassi o classi derivate di quella originaria. Ciascuna sottoclasse è ancora caratterizzata dagli stessi attributi già visti per la classe originaria; è evidente infatti che per esse è possibile precisare la dimensione ,il numero di ruote e la velocità massima. Si dice anche che ciascuna sottoclasse eredita dalla classe di livello superiore, cioè dal suo antenato, tutti gli attributi che sono stati preventivamente definiti. E’ opportuno a questo punto individuare, se esistono, gli attributi specifici di ogni sottoclasse. Per esempio, per la sottoclasse dei veicoli a motore si potrà precisare:



  • il tipo di motore, se a iniezione o a scoppio;

  • un altro parametro significativo può essere la velocità massima che il veicolo può raggiungere;

  • il tipo di trasmissione, se ad albero o mediante una catena; o il numero di giri massimi del motore.

Ne segue che la scheda degli attributi per il veicolo a motore diventa:


La sottoclasse Veicolo a motore può a sua volta avere altre sottoclassi come ad esempio auto



Una volta definita la classe astratta Auto allora diventa possibile creare oggetti Auto, vale a dire creare quelle che vengono chiamate istanze della classe e che rappresentano gli oggetti di lavoro; si potrà avere quindi un oggetto MiaAuto per la quale tutti gli attributi precedentemente specificati, sia quelli della classe che quelli ereditati dai livelli superiori, assumono un valore particolare. MiaAuto sarà individuata per esempio dalla marca Voìkswagen, dalla cilindrata 1300 cc., dal colore bianco e così via.




Affinché una classe sia definita compiutamente è necessario che siano individuate le operazioni possibili sui diversi attributi.


Ad esempio per la nostra classe Veicoli Terrestri possiamo individuare i seguenti metodi:





e per la classe Auto possiamo individuare i seguenti metodi:




METODI COSTRUTTORE E DISTRUTTORE

Tra i metodi appartenenti ad una classe dovrà essere presente il metodo che consente la creazione di un oggetto: il metodo costruttore, e il metodo che permette la distruzione di un oggetto: il metodo distruttore.


Metodo Costruttore: deve essere eseguito per ottenere un oggetto concreto. Il primo effetto del metodo sarà quello di inizializzare alcuni attributi presenti nella classe. il metodo costruttore potrà avere la seguente forma:
Crea nome_oggetto(Attributo1, Attributo2,…,Attributon)
Se ci riferiamo alla classe Veicolo_a_motore e vogliamo creare l’oggetto Mia_Auto possiamo definire il metodo costruttore come segue:
Crea Mia_Auto(Dimensioni,tipo di motore, Velocità massima, Cilindrata, Colore, n° persone trasportate)
Si può notare non ci sono tutti gli attributi, specifici o ereditati, della classe; infatti il metodo crea, e in generale ogni metodo, prevede che alcuni attributi possano essere assegnati per default. Ad esempio, al momento della creazione la velocità attuale sarà impostata a zero. A questo punto possiamo definire due tipi di attributi: gli attributi statici e gli attributi dinamici.

  • una volta definiti per uno specifico oggetto gli attributi statici non subiscono variazioni (dimensione e colore della Mia_Auto)

  • dopo aver assunto un valore, gli attributi dinamici possono essere modificati da metodi specifici (velocità attuale)

Metodo Distruttore: dal punto di vista fisico la creazione di un oggetto fa sì che gli venga riservata un’area di memoria. Per cui, quando l’oggetto non serve più, tale area deve essere liberata, a tale scopo viene utilizzato il metodo distruttore.

ATTRIBUTI E METODI PUBBLICI E PRIVATI

Gli attributi e metodi possono essere pubblici o privati, quelli privati sono completamente invisibili al mondo esterno mentre quelli pubblici permettono all’oggetto di comunicare. Solo i metodi accedono agli attributi assegnandone o modificandone il valore, quindi gli attributi pubblici sono a disposizione del mondo esterno, ma manipolabili solo dai metodi della classe.



OGGETTI E MESSAGGI

U
na volta che,le classi siano disponibili un programmatore che deve risolvere un problema concreto, ha accesso a tali oggetti usando la tecnica dell'invio dei messaggi. Infatti è possibile manipolare,un oggetto attraverso l'invio di un opportuno messaggio: all'atto della ricezione l'oggetto attiva un comportamento determinato eseguendo l'azione richiesta. In generale il nome del messaggio coincide con uno dei metodi ereditati o definiti per quello specifico oggetto. Supponiamo di avere a disposizione la classe Reale e che in essa siano stati definiti i due metodi che eseguono rispettivamente la radice quadrata e il quadrato.


La figura riporta la scheda della classe Reale e dell'oggetto Num al quale è stato assegnato il valore 4. Innanzitutto il programmatore che usi la classe Reale dovrà creare l'oggetto Num con il comando:
Crea Num(4)
A questo punto, poiché sono disponibili tra gli altri due metodi Radice e Quadrato, si può immaginare di inviare i messaggi:
rad=Radice Num;

Pot=Quadrato Num


Gli effetti di tali messaggi possono essere schematizzati nelle seguenti figure:



Il messaggio Radice è inviato all'oggetto Num, il cui valore corrente è 4, e comunica all'oggetto cosa deve fare. A sua volta l'oggetto, avendo il metodo radice al suo interno, lo attiva restituendo la risposta desiderata ovvero un nuovo oggetto Rad di tipo Reale. Analogamente per il messaggio Quadrato.

Prendiamo un secondo esempio. Supponiamo che siano state definite le tre classi Lista, Vettore e Stringa le quali contengano due metodi comuni a tutte.

size che determina il numero di elementi presenti

Att (n) che restituisce la componente di posto n della struttura.

Se Dato è un oggetto di una delle tre classi si potrà avere l'ìnvio dei messaggi

Dirn = Size Dato;

Box = Att(4) Dato;

la cui sintassi non cambia al variare dell'oggetto a cui si riferisce. Se per esempio il Dato è la stringa «Buongiorno» si avrà:
U
n ragionamento analogo lo si può fare il Dato è un vettore di interi, ad esempio:


1

0

2

6

4

avremo che il messaggio size restituisce 5 e il messaggio Att(4) restituisce 6.

Se il primo esempio poteva far pensare che vi fosse un'equivalenza tra l'invio di un messaggio e la chiamata di una funzione in un linguaggio procedurale, l'esempio relativo all'oggetto Dato mostra come la programmazione a oggetti consenta di inviare lo stesso messaggio in un programma a oggetti diversi ottenendo risposte corrette.

Questa potenzialità deriva dal fatto che il messaggio size non corrisponde all'attivazione di una funzione con questo nome, tant'è che ve ne sono tre diverse una per ogni classe, ma è la coppia Messaggio-Oggetto che attiverà il metodo corrispondente al calcolo della dimensione della struttura dati.

I tre oggetti Lista, Vettore e Stringa possiedono ciascuno un metodo avente lo stesso nome Size con implementazioni diverse.

E’ noto a tutti come nella programmazione procedurale la necessità di specificare il tipo dì dato a cui si riferisce la funzione obbliga a dare nomi diversi alla funzione stessa. In questi linguaggi a ogni chiamata di procedura è il compi- latore che fissa una volta per tutte quale parte di codice deve essere eseguita. Si dice che si realizza un legame statico o binding statico.

Nei linguaggi OOP l'esecuzione di un metodo è attivata all'atto dell'esecuzione del programma compilato, vale a dire nel momento in cui si realizza l'associazione tra messaggio e oggetto destinatario. Solo in fase di esecuzione sarà possibile conoscere l'entità coinvolta dal messaggio. Si dice anche che il legame tra il codice e l’oggetto avviene dinamicamente, o anche che si ha un binding dinamico.

Nella OOP, tuttavia, si può operare con entrambi i metodi:


Binding Statico Il compilatore del sistema crea una mappa delle coppie di associazioni metodo-oggetto una volta per tutte. Più veloce ma rigido (bisogna ricompilare tutto ad ogni modifica)

Bindig Dinamico In questo caso l’associazione metodo-oggetto avviene in tempo reale durante l’esecuzione. Più lento ma più flessibile (è diventato il metodo preferito).
INCAPSULAMENTO
Uno degli obiettivi della OOP è quello di realizzare mediante gli oggetti l'incapsulamento o mascheramento dei dati. Per il programmatore che ha familiarità con i linguaggi procedurali è noto come la risoluzione di un problema parta dall'analisi della struttura dati che si intende utilizzare per memorizzare le informazioni, successivamente si individuano gli algoritmi che vengono realizzati mediante procedure o funzioni. I dati sono inviati a tali procedure che eseguono le operazioni restituendo i risultati richiesti. Sappiamo come sia lungo e laborioso il lavoro di riprogettazione ogni volta che sorga una modifica sui dati da elaborare e come sia frequente il fatto che, visti i tempi lunghi di manutenzione dei programmi, sia spesso preferibile procedere a una loro nuova formulazione.

Per ovviare a tali inconvenienti le classi vengono pensate come delle vere e proprie scatole nere con pulsanti, nel senso che l'utilizzatore è a conoscenza di cosa esse sanno fare ma non di come sono state concretamente implementate per rendere possibili tali effetti.

Si può immaginare che un oggetto sia un dispositivo provvisto di pulsanti, uno per ogni metodo, e di corrispondenti porte di uscita o in alternativa linee di comunicazione, che restituiscono, le prime, eventuali oggetti risultato, mentre le seconde inviano un messaggio a un diverso oggetto del sistema. Il programmatore utente può unicamente attivare il pulsante corrispondente all'azione desiderata essendo a conoscenza solamente degli effetti che quel pulsante produce. Con un linguaggio tecnicamente più appropriato il programmatore utente può inviare un messaggio attivando il metodo (pulsante) desiderato senza conoscere nulla relativamente agli attributi e all'implementazione di tale metodo.

La tecnica adottata nella OOP per la definizione di classi è oggetti realizza tali obiettivi a partire dalla possibilità di prevedere parti private e parti pubbliche, sia per quanto si riferisce agli attributi sia per quanto si riferisce ai metodi, con lo scopo evidente di nascondere al programmatore la visibilità dei dati e delle operazioni, impedendone l'accesso e conseguentemente una manipolazione indesiderata.

Per ottenere questo obiettivo si è costruito l'oggetto come insieme inscindibile di due entità, i dati e le operazioni su di essi, e all'atto dell'implementazione concreta questa viene realizzata in modo tale che nell'interfaccia utente siano specificate le operazioni che hanno accesso libero mentre, al contrario, nulla viene detto sui possibili metodi nascosti che pur sono stati concretamente realizzati.

Attributi e metodi privati sono celati all'utente, si dice comunemente che sono incapsulati nell'oggetto e che, lui solo, è in grado di attivarli.

Ricapitolando l’incapsulamento assolve due importanti funzioni di protezione:
protezione dell’utente dall’oggetto: semplifica al massimo l’uso dell’oggetto consentendone di averne una visione astratta (cambiare il volume di un televisore agendo sui circuiti interni).

protezione dell’oggetto dall’utente: non può manipolare l’oggetto (i rischi che corre il televisore)

EREDITARIETA’

Volendo utilizzare una classe simile ma non perfettamente uguale a quelle già disponibili se ne dovrebbe creare una completamente nuova. La OOP ovvia a questo inconveniente introducendo il meccanismo dell’ereditarietà: si crea una classe nuova, ma derivata da una già esistente compiendo quelle modifiche o estensioni che sono necessarie per soddisfare i nuovi bisogni. La nuova classe eredita tutti i metodi e gli attributi della genitrice.



POLIMORFISMO

Per polimorfismo si intende la possibilità di indicare con lo stesso nome dei metodi distinti che esibiscono comportamenti generalmente diversi.



Nella OOP l’aggettivo polimorfo per un metodo viene generalmente riservato a quei casi in cui il compilatore non è in grado di desumere dal contesto quale sarà l’effettiva procedura da chiamare, ma può solo rinviare questa decisione al momento dell’esecuzione sulla base di determinate informazioni che solo allora si potranno conoscere.



©astratto.info 2017
invia messaggio

    Pagina principale