Java è un linguaggio di programmazione orientato agli oggetti (OOL) sviluppato nel 1991 dalla SUN MICROSYSTEMS che si ispira al C++. Java è stato progettato per essere semplice da utilizzare, veloce ed adatto a diverse piattaforme e sistemi operativi.
In altri linguaggi di programmazione l'operazione di compilazione traduce il listato scritto dal programmatore in codice macchina, cioè una serie di istruzioni che vengono interpretate direttamente dal microprocessore, in alcuni casi dal sistema operativo: queste istruzioni variano a seconda dell'architettura della macchina e del sistema operativo, quindi il programmatore si trova costretto a compilare i sorgenti più volte rendendo ogni eseguibile adatto alle diverse piattaforme e ai diversi sistemi operativi.
Esistono anche linguaggi 'interpretati' che non vengono compilati, ma ogni istruzione viene tradotta in codice macchina al momento della sua esecuzione. Questo compito viene svolto dall'interprete, diverso a seconda della piattaforma. Lo svantaggio più evidente dei linguaggi interpretati è la lentezza dell'esecuzione assolutamente incomparabile con la velocità di un programma precompilato. Il vantaggio di questi linguaggi è la portabilità, infatti lo stesso codice viene interpretato diversamente a seconda della piattaforma su cui deve essere eseguito.
Java ha unito i vantaggi di un linguaggio compilato a quelli di uno interpretato. Il sorgente Java viene compilato in un codice intermedio tra il linguaggio macchina e il codice sorgente: il BYTECODE. Il file scritto in Bytecode sarà effettivamente il programma Java. Ogni istruzione scritta in Bytecode viene interpretata dalla JVM ( Java Virtual Machine ). La velocità del programma compilato in Bytecode è molto vicina a quella dei normali programmi compilati ed in più il file compilato è adatto ad ogni piattaforma dove viene installata una JVM, dal PC al telefono cellulare, da Windows a Linux a Unix etc.
In ogni tutorial Java la prima cosa che si spiega sono proprio gli oggetti, a causa della natura stessa del linguaggio. Infatti è impossibile programmare in Java senza conoscere cosa sono gli oggetti. Alla base di tutto c'è il concetto di ADT ( abstract data type - tipo di dato astratto ). Un ADT è un insieme di funzioni e di variabili alle quali si può accedere unicamente tramite le funzioni. Gli oggetti partono proprio da questo concetto, infatti ogni oggetto ha delle caratteristiche e dei comportamenti che agiscono su di esse. Effettivamente se creiamo l'oggetto animale una delle sue caratteristiche sarà lo stomaco pieno o vuoto, ma non si può infilare il cibo direttamente nello stomaco fino a riempirlo, ma tramite il comportamento 'mangiare' lo stomaco si riempirà. Ora per trasformare il concetto astratto di oggetto in concetto programmativo si cambiano due nomi:
'Caratteristiche' diventa 'Variabili' e 'Comportamenti' diventa 'Funzioni'.
Programmando non si andrà a creare un oggetto in particolare, ma si creerà una classe di oggetti, per esempio 'animale'. Poi quando una variabile oggetto appartenente alla classe 'animale' verrà definita per esempio come specie 'Cane' e 'stomaco 'vuoto' allora sarà un cane affamato.
La creazione di una variabile oggetto di una certa classe si chiama 'Creazione di un'istanza di classe' o più semplicemente solo istanza.
Spiegazione dei principali termini utilizzati nella programmazione ad oggetti.
La programmazione ad oggetti nasce dalla necessità di creare un progetto facilmente realizzabile, portabile e aggiornabile. Per raggiungere questi obbiettivi vengono creati dei moduli (classi) ognuno dei quali con compiti ben definiti. Ogni classe deve essere il più possibile indipendente dalle altre, ma nonostante questo, se necessario deve poter comunicare con altre classi/oggetti.
Classico esempio di utilizzo delle classi è il modello ISO-OSI. E' composto da 7 diverse classi, ognuna padre della classe di livello inferiore (esclusa la classe del livello fisico). Nonostante le diverse caratteristiche ogni classe comunica con quella di livello inferiore tramite interfaccia e comunica con classi di livello paritario tramite protocolli.
Gli ADT:
La definizione di oggetto nasce da quella di ADT: Abstract Data Type (tipo di dato astratto). Un ADT è un insieme di variabili e di funzioni che agiscono sulle variabili. Inoltre ADT di tipo diverso devono essere in grado di comunicare tra di loro.
Non sarebbe infatti corretto agire sulle variabili dell'oggetto dall'esterno di esso. Questo per avere la massima indipendenza, infatti se il codice o altri dettagli dell'oggetto dovessero cambiare (nome variabili interne, tipo di una certa variabile etc...) lasciando però intatta la funzionalità dell'oggetto, ogni programma che lo utilizzava deve poter continuare ad essere perfettamente funzionante. Inoltre questo permette di creare o modificare un progetto con una logica modulare senza preoccuparsi per quanto possibile del codice di altre classi, di chi lo ha scritto o dei programmi che ne fanno uso. Nonostante questo spesso è utile creare delle parentele tra oggetti in modo che una classe erediti proprietà da una classe padre non dimenticando però che ogni classe deve essere per quanto possibile indipendente dalle altre. La progettazione di un programma ad oggetti viene fatta attravesro lo standard UML che permette di dividere un problema in una serie di sottoproblemi logicamente divisi in classi di appartenenza.
Classe: ogni classe è un insieme di oggetti che hanno le stesse proprietà. Si parla di classe nella parte di codice dove viene definita e dichiarata, oppure nella parte di analisi di un progetto.
Oggetto: quando si crea una variabile di una classe la variabile si chiama oggetto.
Metodo: funzione appartenente ad una classe/oggetto
Proprietà: variabile appartenente ad una classe/oggetto
Istanza: creazione di un oggetto di una certa classe. Un oggetto viene istanziato quando, in una porzione di programma, si assegna ad una variabile (spesso un puntatore) una porzione di memoria in vengono caricate proprietà e metodi della relativa classe.
Definizione e dichiarazione: porzione di codice che definisce le proprietà ed i metodi di una classe.
Ereditarietà: una classe che viene definita come figlia di un altra (o altre) ne eredita tutte le proprietà ed i metodi.
Costruttore: in una classe può essere presente uno o più metodi che vengono definiti con lo stesso nome della classe (tra loro si differenziano per tipo o numero di argomenti). Questo metodo viene invocato automaticamente quando un oggetto viene istanziato e solitamente serve per inizializzare le proprietà dell'oggetto. Se una classe ha uno o più padri anche i costruttori dei padri vengono automaticamente invocati.
Distruttore: in una classe può essere presente un solo metodo distruttore che viene invocato quando un oggetto viene distrutto tramite "delete NomeVariabileOggetto;". Solitamente veniva utilizzato per deallocare la memoria occupata dall'oggetto, ormai nei linguaggi orientati agli oggetti (C++, java, visual C++, Delphi, etc...) l'operazione di deallocazione viene eseguita in automatico. Il distruttore è definito con la sintassi " ~NomeClasse () " (senza argomenti).
Invocazione: un metodo viene invocato quando una certa porzione di codice ne fa uso.
Overloading: una classe figlio può ridefinire (quindi usando stesso nome metodo, numero e tipo argomenti ) un metodo definito nella classe padre. Se viene invocato verrà utilizzato quello della classe figlio, come se nella classe padre non esistesse.
--NUOVO CHIARIMENTO -- Con il termine overloading si indica principalmente la definizione,in una stessa classe,di più funzioni con stesso nome ma argomenti differenti.IN JAVA è inoltre possibile effettuare un overloading in classi figlio ridefinendo metodi della classe padre anche utilizzando la medesima firma. Non servono particolari parole chiave per effettuare questa operazione, e non è obbligatorio invocare il metodo ridefinito della classe padre, nonostante spesso sia utile. Questa particolare operazione di ridefinizione di metodi con uguale firma prende anche il nome di Overriding
--FINE NUOVO CHIARIMENTO--
Overriding: Particolare operazione di overloading su metodi con uguale firma ma appartenenti a classi diverse, ma in parentela tra loro. Spesso in un metodo ridefinito è utilizzata l'invocazione di un metodo della classe padre nella definizione della classe figlio. Se ne fa spesso uso per invocare il costruttore della classe padre o per invocare metodi in overloading (sempre dalla classe figlio verso una delle classi padri).
Interfaccia: Metodo di collegamento tra due o più oggetti che permette il trasferimento di dati da uno all'altro.
this: Parola chiave che viene utilizzata solo all'interno di una classe. "this" indica l'oggetto che ha invocato il metodo. Solitamente this è indicato come l'oggetto (e non la classe!) che attualmente stà eseguendo il metodo.
Presto un box esplicativo con esempi IN JAVA.