In questo corso vedremo Java come caso di linguaggio di programmazione orientato a oggetti (object-oriented programming language).
Siccome la pratica e' la parte che riesce piu' difficile, quest'anno partiamo proprio da quella. Vediamo subito un esempio...
In un linguaggio imperativo tradizionale (non O.O.) ci sono:
Il tipo "rettangolo" e' un record con due interi per lunghezza e larghezza. La funzione "area" prende un rettangolo e ne ritorna l'area. La funzione "print" stampa un rettangolo.
#include <stdio.h> typedef struct { int length, width; } Rectangle; int area(Rectangle r) { return r.length * r.width; } void print(Rectangle r) { printf("Rettangolo %d x %d\n",r.length,r.width); } void main() { Rectangle r; int a; r.length = 3; r.width = 5; a = area(r); print(r); printf("Area = %d\n",a); }
In un linguaggio object oriented:
La classe "rettangolo" ha due interi per lunghezza e larghezza, un metodo "area" che ritorna l'area del rettangolo e un metodo "print" che stampa il rettangolo.
class Rectangle { int length, width; int area() { return length * width; } void print() { System.out.println("Rectangle " + length + " x " + width); } public static void main(String[] args) { Rectangle r = new Rectangle(); int a; r.length = 3; r.width = 5; a = r.area(); r.print(); System.out.println("Area = " + a); } }
Convenzione: in Java i nomi di classe hanno iniziale maiuscola, gli altri nomi iniziale minuscola. Se un nome e' fatto da piu' parole, le successive hanno iniziale maiuscola (es. "printArea").
Notazione analoga alla selezione di un campo di un record. Ma e' una funzione, quindi ha sempre le () e puo' avere argomenti. Es. se r e' un rettangolo:
L'oggetto su cui si chiama il metodo e' argomento privilegiato del metodo.
All'interno dell'implementazione del metodo, l'argomento privilegiato
e' lasciato implicito. Es. nel metodo
int area() { return length * width; }si intende che length e width appartengono al rettangolo su cui sara' chiamata la funzione (r se chiamata con r.area()).
Una classe e' l'analogo di un tipo ma comprende anche le funzioni
che agiscono su quel tipo.
E' come un record dove alcuni campi sono variabili ed altri sono funzioni.
Come si dice "un valore di un tipo" cosi' si dice "un oggetto di una classe". Si dice anche che un oggetto e' istanza della sua classe.
Un oggetto ha:
Java e' linguaggio totalmente object oriented. A parte i tipi base (int, float, double, boolean, char) tutti gli altri tipi sono classi. E tutte le funzioni appartengono a qualche classe.
Anche il "main" e' una funzione in una classe, che deve avere i seguenti parametri:
public static void main(String[] args)Posso "eseguire" qualsiasi classe contenga questa funzione. Quello che viene eseguito e' il main.
Il programmatore scrive il sorgente del programma in un linguaggio di programmazione. Tale linguaggio e' comprensibile all'uomo ma non dalla macchina.
Per poter essere eseguito dalla macchina, il sorgente deve essere tradotto nel linguaggio proprio della macchina, che e' binario e incomprensibile all'uomo.
Questa traduzione puo' avvenire in due modi:
Mediante compilatore:
la traduzione avviene una volta per tutte e il programma tradotto
viene memorizzato in un file eseguibile.
L'eseguibile puo' poi essere mandato in esecuzione
senza bisogno di essere tradotto di nuovo e quindi senza bisogno
di avere il file sorgente e il compilatore.
L'esecuzione e' veloce.
Ma funziona solo su macchine che abbiano la stessa architettura
di dove e' stato compilato.
Perche' l'eseguibile e' scritto nel linguaggio binario specifico di questa
macchina con questo sistema operativo.
Mediante interprete:
la traduzione avviene al momento stesso dell'esecuzione
e va ripetuta ogni volta.
Di fatto ad essere eseguito e' l'interprete, il quale
carica il file sorgente e lo esamina
una istruzione alla volta, traducendo
man mano la prossima istruzione che deve essere eseguita.
Per poter eseguire il programma, ho bisogno sempre del file
sorgente e dell'interprete. L'esecuzione e' lenta.
Pero' il programma (in quanto sorgente non compilato)
rimane portabile su
qualsiasi architettura, purche' vi sia installato l'interprete.
Potremmo riassumere:
I progettisti di Java hanno voluto fondere i vantaggi di entrambe le
tecniche (slogan di java: "compile once, execute everywhere").
Java e' linguaggio pensato per generare programmi portabili su piattaforme
diverse senza essere (interamente) ri-tradotti.
L'esecuzione e' abbastanza veloce (il grosso della traduzione e' stato
gia' fatto in compilazione).
In caso di errori run-time, l'interprete riporta esattamente dove
(quale funzione, quale linea...).
Java e' distribuito in due diversi pacchetti:
Java e' distribuito gratuitamente in rete per solaris / windows / linux. Sito: http://java.sun.com/ (scegliere "Downloads" dalla barra in alto e "JavaSE" nel menu', a noi interessa JSDK). d
I sorgenti java possono essere scritti con qualsiasi editor di testi. Importante: se si usa un word processor (come MS-Word) salvare in formato "solo testo", senza formattazione.
Una classe va salvata su file con stesso nome
della classe ed estensione .java
(es. Rectangle.java per la classe Rectangle).
Attenzione: quando si salva in formato "solo testo", l'editor
potrebbe dare automaticamente estensione .txt: bisogna ricordarsi di
cambiarla.
Alcuni sistemi (es. Windows) permettono di chiamare il file sorgente con un nome diverso dal nome della classe. Pero' il file bytecode generato dal compilatore porta sempre il nome della classe. Esempio:
Un programma puo' consistere di piu' classi e piu' file (un file per classe). Java rintraccia automaticamente i file che servono, purche' siano nella directory corrente.
La versione di Java installata in laboratorio e' la 1.4 in PC2 e 1.6 in PC1.
I sorgenti devono essere prima compilati e poi eseguiti.
Abbiamo detto che la funzione "main" deve essere dichiarata come:
public static void main(String[] args)
Gli argomenti della funzione "main" sono i parametri dati su
command-line quando si lancia il programma.
Esempio:
java Rectangle 12 13Nella funzione main ritrovo:
I parametri da command-line arrivano al "main" sempre come oggetti di tipo stringa. Ma tali stringhe possono rappresentare numeri interi o float ecc. Come ottenere dalla stringa il valore numerico?
public static void main(String[] args) { if (args.length!=2) System.out.println("Need two arguments"); else { int l = Integer.parseInt(args[0]); int w = Integer.parseInt(args[1]); System.out.println("Read arguments " + l + " " + w); Rectangle r = new Rectangle(); int a; r.length = l; r.width = w; a = r.area(); r.print(); System.out.println("Area = " + a); } }
Java ha una grande libreria di classi predefinite (Java Foundation Classes, JFC), tra cui:
Manuale dei package e delle classi predefinite Java disponibile in rete ( http://java.sun.com/j2se/1.4.2/docs/api/).