Mappa
TOPIC
Introduzione
Il nome piattaforma \xE8 giustificato dal fatto che con Java non si pu\xF2 intendere solo il linguaggio ma quasto va integrato con la Java Virtual Machine che \xE8 appunto una macchina virtuale ( vedi Tannenbaum ) per la quale viene compilato il linguaggio. Una breve ed efficace presentazione dell'architettura del linguaggio Java \xE8 disponibile
QUI
L'Architettura
Gli strati che compongono la tecnologia Java sono sintetizzati nella figura a Fianco. L'aspetto peculiare \xE8 il fatto che Java \xE8 una *piattaforma completamente software* |
|
la Piattaforma Java ha due componenti essenziali:
- La Java Virtual Machine (macchina Virtuale Java)
- La API Java (Java Application Program Interface)
|
|
E' il Java launcher tool che insieme all'applicazione Java si occupa di lanciare anche la Java Virtual Machine
il Linguaggio
Il sito Oracle mette a disposizione un
Wite Paper con una efficace intriduzione al linguaggio.
La Convenzione del Nome dei File Sorgente di Java
Usualmente il codice sorgente dovrebbe essere salvato in un file il cui nome si basa sul nome della classe. Per esempio il seguente codice definendo la classe
pippo
import java.awt.*;
public class pippo extends Component
{
// .....
}
dovrebbe essere salvato nel file
pippo.java
Variabili
I nomi di variabile riconoscono maiuscole e minuscole e
non possono iniziare con un numero .
Tipi di dati primitivi
Integere Numeric |
|
|
|
byte |
8-bit |
|
short |
16-bit |
|
int |
32-bit |
|
long |
64-bit |
Real Numeric |
|
|
|
float |
32-bit |
|
double |
64-bit |
Character Data type |
|
|
|
char |
16-bit Unicode character |
|
|
char myChar 'Testo' ; |
Boolean Data type |
|
|
|
boolean |
true or false |
Array
Le tabelle sono degli oggetti che hanno una rappresentazione a livello di run-time quindi vengono gestiti a livello di macchina virtuale.
Un array viene diachiarato con una sintassi simile al C
float myFloat[];
La precedente sintassi,bench\xE8 corretta
\xE8 deprecata. . La dichiarazione dell'array non alloca la memoria ma definisce solo la tipologia dell'array.
float[] myFloat;
byte[] anArrayOfBytes;
short[] anArrayOfShorts;
long[] anArrayOfLongs;
L'allocazione reale di memoria viene fatta con l'utilizzo dell'operatore
new
// create an array of integers
anArray = new int[10];
La sua inizializzazione pu\xF2 essere fatta contestualmente alla allocazione con la seguente sintassi dove vengono usate le
{ }
int[] anArray = {
100, 200, 300,
400, 500, 600,
700, 800, 900, 1000
};
Per accedere agli elementi di un array si usa la sintassi classica del C/C++
float myFloat[];
int i;
for (i = 0; i < 10; i++) {
myPoints[i] = new Point();
}
Il dimensionamento \xE8 dinamico, l'istanza
myFloat.length
restituisce il numero di elementi dell'0array
String
Il tipo "String" \xE8 a tutti gli effetti un oggetto. Esistono due tipi di "oggetti string" uno immutabile, costante
String
ed uno modificabile
StringBuffer
. L'assegnazione anzich\xE8 seguire la sintassi tipica dell'istansazione diun oggetto segue quella tipicadel linguaggio C
String hello = "Hello world!";
System.out.println("There are " + num + " characters in the file.");
Ilsimbolo
+
puo essere usato per la concatenazione di pi\xF9 variabili string in un'unica variabile.
Per una completa comprensione e' preferibile affrontare questa sezione dopo aver visto i concetti di oggetto e metodo. La sezione si trova
Qui
Operatori
Tabella completa
QUI
Operators |
Precedence |
postfix |
expr++ expr-- |
unary |
=++expr --expr +expr -expr ~ != |
multiplicative |
* / % |
additive |
+ - |
shift |
<< >> >>> |
relational |
< > <= >= instanceof |
equality |
== != |
bitwise AND |
& |
bitwise exclusive OR |
^ |
bitwise inclusive OR |
| |
logical AND |
&& |
logical OR |
|| |
ternary |
? : |
assignment |
= += -= *= /= %= &= ^= |= <<= >>= >>>=| |
Operatori di Ordine
== equal to
!= not equal to
> greater than
>= greater than or equal to
< less than
<= less than or equal to
Operatori Logici
&& Conditional-AND
|| Conditional-OR
L'operatore
instanceof
controlla l'appartenenza di un oggetto ad una determinata classe
class InstanceofDemo {
public static void main(String[] args) {
Parent obj1 = new Parent();
Parent obj2 = new Child();
System.out.println("obj1 instanceof Parent: "
+ (obj1 instanceof Parent));
System.out.println("obj1 instanceof Child: "
+ (obj1 instanceof Child));
.....
}
}
Istruzioni per il Controllo di Flusso
if then
e if then else
L' if- then \xE8 il pi\xF9 fondamentale di tutte le istruzioni di controllo . Dice al tuo programma di eseguire una determinata sezione di codice solo se "express" restituisce true (vero). Ad esempio, la classe Bicicletta potrebbe consentire i freni per diminuire la velocit\xE0 della bicicletta solo se la bicicletta \xE8 gi\xE0 in movimento . Una possibile implementazione del metodo applyBrakes potrebbe essere il seguente :
void applyBrakes() {
// the "if" clause: bicycle must be moving
if (isMoving){
// isMoving=express
// the "then" clause: decrease current speed
currentSpeed--;
}
}
Se questo test restituisce false (ovvero la bicicletta non \xE8 in movimento ) , il controllo passa alla fine della dichiarazione if-then .
Inoltre , le parentesi di apertura e chiusura sono opzionali , a condizione che il " poi " clausola contiene una sola istruzione :
void applyBrakes() {
// same as above, but without braces
if (isMoving)
currentSpeed--;
}
L'istruzione switch
The switch Statement
A differenza di if-then e if-then-else, l'istruzione switch pu\xF2 avere un numero di possibili percorsi di esecuzione. Un interruttore funziona con il byte, short, char, e tipi di dati primitivi int. Funziona anche con tipi enumerati, la classe String, e alcune classi speciali che avvolgono alcuni tipi di dati primitivi: Carattere, byte, short, e Integer (discusso in numeri e stringhe).
Il seguente esempio di codice,
SwitchDemo, dichiara un int mese denominato il cui valore rappresenta un mese. Il codice visualizza il nome del mese, in base al valore del mese, utilizzando switch.
public class SwitchDemo {
public static void main(String[] args) {
int month = 8;
String monthString;
switch (month) {
case 1: monthString = "January";
break;
case 2: monthString = "February";
break;
case 3: monthString = "March";
break;
case 4: monthString = "April";
break;
case 5: monthString = "May";
break;
case 6: monthString = "June";
break;
case 7: monthString = "July";
break;
case 8: monthString = "August";
break;
case 9: monthString = "September";
break;
case 10: monthString = "October";
break;
case 11: monthString = "November";
break;
case 12: monthString = "December";
break;
default: monthString = "Invalid month";
break;
}
System.out.println(monthString);
}
}
In questo caso, Agosto viene stampato sullo standard output.
Il corpo di un'istruzione switch \xE8 noto come un blocco di commutazione. Una dichiarazione nel blocco switch pu\xF2 essere etichettato con una o pi\xF9 etichette predefinite. L'istruzione switch valuta la sua espressione, quindi esegue tutte le istruzioni che seguono l'etichetta di corrispondenza.
.
L'Istruzione while
e do-while
L'istruzione
while
esegue continuamente
statement(s)
mentre una particolare espressione
expr
\xE8 vera. La sua sintassi pu\xF2 essere espresso come:
while (expr) {
statement(s)
}
L' istruzione
while
valuta l'espressione
expr
, che deve restituire un valore booleano. Se l'espressione
expr
restituisce true, l'istruzione
while
esegue
statement(s)
nel blocco
while
. L' istruzione
while
continua a testare l'espressione
expr
e l'esecuzione di suo blocco fino a quando l'espressione
expr
restituisce false. Utilizzando l'istruzione
while
per stampare i valori da 1 a 10 pu\xF2 essere realizzato come nel seguente programma WhileDemo:
class WhileDemo {
public static void main(String[] args){
int count = 1;
while (count < 11) {
System.out.println("Count is: " + count);
count++;
}
}
}
\xC8 possibile implementare un loop infinito utilizzando l' istruzione
while
come segue:
while (true){
// your code goes here
}
Il linguaggio Java fornisce anche un comando
do - while
, che pu\xF2 essere espresso come segue:
do {
statement(s)
} while (expression);
La differenza tra
do- while
e
while
\xE8 che
do- while
ha la sua espressione
expr
nella parte inferiore del ciclo anzich\xE9 in alto. Pertanto, le
statement(s)
all'interno del blocco do vengono sempre eseguiti almeno una volta, come mostrato nella seguente programma DoWhileDemo :
class DoWhileDemo {
public static void main(String[] args){
int count = 1;
do {
System.out.println("Count is: " + count);
count++;
} while (count < 11);
}
}
L'Istruzione for
L'istruzione
for
fornisce un modo compatto per
iterare su un intervallo di valori. I programmatori spesso si riferiscono ad esso come il "for loop", perch\xE8 essa si ripete un numero di volte pari ad il numero di valori nell'intervllo.
L' istruzione
for
pu\xF2 essere espressa come segue:
for (initialization; termination;
increment) {
statement(s)
} |
- initialization inizializza il ciclo;
- quando termination \xE8 falsa, il ciclo termina;
- increment viene richiamato dopo ogni iterazione del ciclo, serve ad incrementare o decrementare un valore;
|
Il seguente programma \xE8 un esempio di come utilizzare la forma generale dell'istruzione
for
; nell'esempio, l'istruzione
for
viene usata per stampare i numeri da 1 a 10:
class ForDemo {
public static void main(String[] args){
for(int i=1; i<11; i++){
System.out.println("Count is: " + i);
}
}
}
Notate come il codice dichiara una variabile all'interno dell'espressione di inizializzazione. L'ambito (l'ambito di un identificatore \xE8 la regione del programma, all'interno del quale rappresenta una certa cosa) di questa variabile si estende dalla sua dichiarazione alla fine del blocco disciplinato dall'istruzione
for
, in modo che possa essere utilizzato nell' espressioni di terminazione e d' incremento. Se la variabile che controlla l'istruzione
for
non \xE8 necessaria al di fuori del ciclo, \xE8 meglio dichiarare la variabile nell'espressione di inizializzazione. Le tre espressioni del ciclo
for
(initialization, termination, increment) sono opzionali; un ciclo infinito pu\xF2 essere creato come segue:
// infinite loop
for ( ; ; ) {
// your code goes here
}
L'istruzione
for
ha anche un'altra forma progettata per l'iterazione attraverso Collections e array. Questa forma pu\xF2 essere utilizzata per rendere i loop pi\xF9 compatti e di facile lettura.
class EnhancedForDemo {
public static void main(String[] args){
int[] numbers =
{1,2,3,4,5,6,7,8,9,10};
for (int item : numbers) {
System.out.println("Count is: " + item);
}
}
}
Le Istruzione break
, continue
e return
L'istruzione break
L'istruzione break ha due forme: con etichetta e senza etichetta. Hai visto la forma non marcata nella discussione precedente dell'istruzione switch. \xC8 inoltre possibile utilizzare una pausa senza etichetta per terminare un for, while, o do-while, come mostrato nella seguente programma BreakDemo:
class BreakDemo {
public static void main(String[] args) {
int[] arrayOfInts =
{ 32, 87, 3, 589,
12, 1076, 2000,
8, 622, 127 };
int searchfor = 12;
int i;
boolean foundIt = false;
for (i = 0; i < arrayOfInts.length; i++) {
if (arrayOfInts[i] == searchfor) {
foundIt = true;
*break*;
}
}
if (foundIt) {
System.out.println("Found " + searchfor + " at index " + i);
} else {
System.out.println(searchfor + " not in the array");
}
}
}
Questo programma cerca il numero 12 in un array. L'istruzione break, indicato in grassetto, termina il ciclo for quando viene rilevato tale valore. Controllo di flusso poi il trasferimento alla dichiarazione dopo il ciclo for.
L'istruzione break termina l'istruzione etichettata; non trasferisce il flusso di controllo per l'etichetta. Il flusso di controllo viene trasferito all'istruzione immediatamente dopo il "terminato".
L'istruzione continue
L'istruzione
continue salta l'iterazione di un for, while, o do-while. La forma non marcata salta alla fine del corpo del ciclo pi\xF9 interno e valuta l'espressione booleana che controlla il ciclo. Il programma seguente, ContinueDemo, passa attraverso una stringa, contando le occorrenze della lettera "p". Se il carattere corrente non \xE8 una p, l'istruzione continue salta il resto del ciclo e procede al carattere successivo. Se invece \xE8 una "p", il programma incrementa il conteggio della lettera:
class ContinueDemo {
public static void main(String[] args) {
String searchMe = "peter piper picked a " + "peck of pickled peppers";
int max = searchMe.length();
int numPs = 0;
for (int i = 0; i < max; i++) {
// interested only in p's
if (searchMe.charAt(i) != 'p')
*continue*;
// process p's
numPs++;
}
System.out.println("Found " + numPs + " p's in the string.");
}
}
Per vedere questo effetto in modo pi\xF9 chiaro basta rimuovere l'istruzione
continue e ricompilarlo. Quando si esegue nuovamente il programma, il conteggio sar\xE0 sbagliato.
L'istruzione return
L'ultima delle dichiarazioni di ramificazione \xE8 l'istruzione return. L'istruzione return esce dal metodo corrente, e il flusso di controllo ritorna al punto in cui \xE8 stato richiamato il metodo. L'istruzione return ha due forme: una che restituisce un valore, e uno che non lo fa. Per restituire un valore, \xE8 sufficiente mettere il valore (o un'espressione che calcola il valore), dopo la parola chiave return
ritorno ++ contare;
Il tipo di dati del valore restituito deve corrispondere al tipo di valore di ritorno del metodo dichiarato. Quando un metodo viene dichiarato nullo, usa il modulo di ritorno che non restituisce un valore
ritorno.
Operatori Logici
Gli Operatori di relazione e di uguaglianza determinano se un operando \xE8 maggiore, minore, uguale o non uguale ad un altro operando. La maggior parte di questi operatori vi potr\xE0 risultare familiare. Tenete a mente che si deve usare "==", non "=", durante la prova se due valori primitivi sono uguali.
== equal to
!= not equal to
> greater than
>= greater than or equal to
< less than
<= less than or equal to
Il programma seguente, ComparisonDemo, verifica gli operatori di confronto:
class ComparisonDemo {
public static void main(String[] args){
int value1 = 1;
int value2 = 2;
if(value1 == value2)
System.out.println("value1 == value2");
if(value1 != value2)
System.out.println("value1 != value2");
if(value1 > value2)
System.out.println("value1 > value2");
if(value1 < value2)
System.out.println("value1 < value2");
if(value1 <= value2)
System.out.println("value1 <= value2");
}
}
Operatori Condizionali
Il && e || sono operatori che eseguono Conditional-AND and Conditional-OR e operazioni condizionali o su due variabili booleane. Questi operatori presentano un comportamento detto a "corto-circuito", ci\xF2 significa che il secondo operando viene valutato solo se necessario.
&& Conditional-AND
|| Conditional-OR
Il programma seguente, ConditionalDemo1, testa questi operatori:
class ConditionalDemo1 {
public static void main(String[] args){
int value1 = 1;
int value2 = 2;
if((value1 == 1) && (value2 == 2))
System.out.println("value1 is 1 AND value2 is 2");
if((value1 == 1) || (value2 == 1))
System.out.println("value1 is 1 OR value2 is 1");
}
}
Un altro operatore condizionale \xE8:?, Che pu\xF2 essere pensato come abbreviazione di un if-then-else (discussa nella sezione Controllo flusso dichiarazioni di questa lezione). Questo operatore \xE8 anche conosciuto come l'operatore ternario perch\xE9 utilizza tre operandi. Nel seguente esempio, questo operatore deve essere letto come: "Se someCondition \xE8 vero, si deve assegnare il valore di valore1, altrimenti assegnare il valore di valore2 al risultato.\xBB.
Il programma seguente, ConditionalDemo2, verifica l': operatore?:
class ConditionalDemo2 {
public static void main(String[] args){
int value1 = 1;
int value2 = 2;
int result;
boolean someCondition = true;
result = someCondition ? value1 : value2;
System.out.println(result);
}
}
Perch\xE9 someCondition \xE8 vero, questo programma stampa "1" nella schermata. Conviene utilizzare l'operatore invece di un'istruzione if-then-else se ci\xF2 rende il codice pi\xF9 leggibile;? per esempio, quando le espressioni sono senza effetti collaterali e compatte (quali assegnazioni).
Il tipo Instance Of (Operatore di confronto)
L'operatore instanceof paragona un oggetto a un tipo specificato. Si pu\xF2 usare per verificare se un oggetto \xE8 un'istanza di una classe, un'istanza di una sottoclasse, o un'istanza di una classe che implementa una particolare interfaccia.
Il programma seguente, InstanceofDemo, definisce una classe genitore (denominata Parent), una semplice interfaccia (denominata MyInterface), e una classe figlia (denominata Bambino) che eredita dal genitore e implementa l'interfaccia.
class InstanceofDemo {
public static void main(String[] args) {
Parent obj1 = new Parent();
Parent obj2 = new Child();
System.out.println("obj1 instanceof Parent: "
+ (obj1 instanceof Parent));
System.out.println("obj1 instanceof Child: "
+ (obj1 instanceof Child));
System.out.println("obj1 instanceof MyInterface: "
+ (obj1 instanceof MyInterface));
System.out.println("obj2 instanceof Parent: "
+ (obj2 instanceof Parent));
System.out.println("obj2 instanceof Child: "
+ (obj2 instanceof Child));
System.out.println("obj2 instanceof MyInterface: "
+ (obj2 instanceof MyInterface));
}
}
class Parent {}
class Child extends Parent implements MyInterface {}
interface MyInterface {}
Quando si utilizza l'operatore instanceof, bisogna tenere a mente che nulla non \xE8 un'istanza di nulla.
Linguaggio Orientato agli Oggetti
Gli aspetti principali sono:
- Encapsulation--implements information hiding and modularity (abstraction)
- Polymorphism--the same message sent to different objects results in behavior that's dependent on the nature of the object receiving the message
- Inheritance--you define new classes and behavior based on existing classes to obtain code re-use and code organization
- Dynamic binding--objects could come from anywhere, possibly across the network. You need to be able to send messages to objects without having to know their specific type at the time you write your code. Dynamic binding provides maximum flexibility while a program is executing
Ogni oggetto \xE8 definito dalle sue
- Instance variables sono i dati incapsulati all'interno dell'oggetto che ne definiscono il comportamento
- metodi codice che agendo sui dati modifica lo stato delll'oggetto
Classi
Una classe \xE8 il particolare inieme di codice che viene richiamato durante la definizione di un oggetto da parte dul modulo applicativo del programma. La classe \xE8 costituita da:
- Campi (Field) cio\xE8 dati
- metodi cio\xE8 istruzioni che operano sui campi
Ecco un esempio
class Point extends Object {
public double x; /* instance variable */
public double y; /* instance variable */
}
Tipi dei Membri delle Classi ( Variabile di Stato, "Istance Variables" e Metodi )
Le variabili di "stato" possono assumere 4 diversi protocolli per ci\xF2 che concerne la loro interazione con i processi esterni alla classe
-
private
I membri definiti in questo modo sono accessibili solo dall' interno del codice della classe stessa; la loro manipolazione pu\xF2 avvenire solo attraverso il " passaggio di messaggi " con codice esterno.
-
public
I membri cos\xEC definiti sono accessibili a chiunque
-
protected
i menbri cos\xEC definiti sono acccessibili solo alle loro sottoclassi (subclass)
- "non dichiarato" i menbri che non vengono dichiarati sono assunti amichevoli (frinedly) e sono acccessibili dalle classi dello stesso package
I valori assunti da queste variabili sono diversi per ogni oggetto appartenente alla classe
Istanziazione di una Classe
Si intende la definizione di un oggetto (variabile) appartenente all'insieme definito dalla
classe (la classe infatti definisce la propriet\xE0 caratteristica dell'insieme )
Point myPoint; // declares a variable to refer to a Point object
myPoint = new Point(); // allocates an instance of a Point object
La
keyword new
definisce l'inizializzazione dell'oggetto. Il riferimento all'istanza usa la sintassi classica del C
myPoint.x = 10.0;
myPoint.y = 25.7;
Static Variable
le variabili statiche assumono valori associati
alla classe anzich\xE8 all'oggetto generato (istanziato) per questo vengono precedute alla keyword
static
Constructor
I "Constructor" sono metodi,
con lo stesso nome della classe, che vengono chiamati nel momento in cui si "istanzia" un oggetto della classe. Inizializzano le istanze dell'oggetto oppure assegnano dei valori definiti successivamente all'istanzazione dell'oggetto. L'esempio precedente viene ad essere cos\xEC modificato:
class Point extends Object {
public double x; /* instance variable */
public double y; /* instance variable */
Point() { /* constructor to initialize to default zero value */
x = 0.0;
y = 0.0;
}
/* constructor to initialize to specific value
Point(double x, double y) {
this.x = x; /* set instance variables to passed parameters */
this.y = y;
}
}
la variabile this
All'interno del codice di una classe per riferirsi affermare che ci si sta riferendo alle istanze della stessa classe si pu\xF2 usare l'istanza
this come si \xE8 fatto nell'esempio precedente:
Point(double x, double y) {
this.x = x; /* set instance variables to passed parameters */
this.y = y;
}
}
Sotto-Classi
Le Classi posso essere
estese (extended) attraverso le
Sotto Classi Il codice che definisce la sotto-classe arricchisce la classificazione, dovendo fornire la propriet\xE0 caratteristica
del sottoinsieme della classe originaria. La sottoclasse in termini di relazioni fornite contiene come sottoinsieme la classe mentre da origine ad un sottoinsieme contenuto nella "classe originaria"
class ThreePoint extends Point {
protected double z; /* the z coordinate of the point */
ThreePoint() { /* default constructor */
x = 0.0; /* initialize the coordinates */
y = 0.0;
z = 0.0;
}
ThreePoint(double x, double y, double z) {/* specific constructor */
this.x = x; /* initialize the coordinates */
this.y = y;
this.z = z;
}
}
La parola
extend
impartisce al compilatore Java il comando di considerare la classe
ThreePoint
come una sottoclasse di
Point
. Essendo una estensione \xE8 necessario definire solo la "istance variable"
z
, e perch\xE8 questo possa accadere le variabili si stato debbono essere definite come
protected
in modo che siano disponibili a tutte le sotto-classi. Un altra modalit\xE0 di accesso alle variabili di stato della
superclasse verr\xE0 definito nel punto successivo attraverso la parola chiave
super
class Point extends Object {
protected double x; /* instance variable */
protected double y; /* instance variable */
Point() { /* constructor to initialize to zero */
x = 0.0;
y = 0.0;
}
}
class ThreePoint extends Point
{
protected double z; /* the z coordinate of the point */
ThreePoint()
{ /* default constructor */
x = 0.0; /* initialize the coordinates */
y = 0.0;
z = 0.0;
}
ThreePoint(double x, double y, double z)
{ /* specific constructor */
this.x = x; /* initialize the coordinates */
this.y = y;
this.z = z;
}
}
Ereditariet\xE0 Singola
Ogni sottoclasse pu\xF2 avere solo una classe di livello superiore cio\xE8 pu\xE0 essere
estensione di una sola classe.
Override e super
Nella definizione di una sottoclasse pu\xF2 essere necessario "sostituire" (override=scavalcare) un metodo della
superclasse, quindi tutti gli elementi del sottoinisieme definito dalla sottoclasse faranno riferimento al nuovo metodo. Si avr\xE0 sicuramente all'interno del codice della sottoclasse la necessit\xE0 di riferirsi al metodo della super classe e questo lo si fa con la parola chiave
super
public class Subclass extends Superclass {
// overrides printMethod in Superclass
public void printMethod() {
super.printMethod();
System.out.println("Printed in Subclass");
}
public static void main(String[] args) {
Subclass s = new Subclass();
s.printMethod();
}
}
La chiamata al metodo
constructror della superclasse pu\xF2 essere fatto con una sintassi pi\xF9 semplice come la seguente in cui la chiamata al metodo
super
deve trovarsi nella prima riga del constructor della sottoclasse
public MountainBike(int startHeight,
int startCadence,
int startSpeed,
int startGear) {
super(startCadence, startSpeed, startGear);
seatHeight = startHeight;
}
Metodi e Messaggi
Usando il paradigma del
passaggio di messaggi tra le varie classi si pu\xF2 cambiare il valore delle
variabili di stato e quindi organizzare il funzionamento del programma. Questo obiettivo viene raggiunto attraverso la definizione di opportuni metodi.
Accessor Method
I metodi
Accessor permettono di
accedere alle informazioni che difiniscono l'oggetto sia per poterle
modificare che per
leggerle
Qui un esempio di un metodo definito per impostare i valori delle variabili di stato della classe
Point
, dove le variabili tornano ad essere
private
class Point extends Object {
private double x; /* instance variable */
private double y; /* instance variable */
Point() { /* constructor to initialize to zero */
x = 0.0;
y = 0.0;
}
/* constructor to initialize to specific value */
Point(double x, double y) {
this.x = x;
this.y = y;
}
public void setX(double x) { /* accessor method */
this.x = x;
}
public void setY(double y) { /* accessor method */
this.y = y;
}
public double getX() { /* accessor method */
return x;
}
public double getY() { /* accessor method */
return y;
}
}
Variabili di Classe (Class Variables)
Le variabili di classe sono varibaili interne al codice che definisce la classe non ne definiscono lo stato quindi la generazione di un oggetto di quella classe non implica la presenza di tali variabili all'interno dell'oggetto creato,
come invece avviene nel caso delle variabili di stato . Per definire una variabile di classe (Class variable) o un metodo di classe (Class Method) si usa la parola chiave
static
class Rectangle extends Object {
static final int version = 2;
static final int revision = 0;
}
Classi "Generiche" (Abstract Classes)
Le classi generiche permettono di definire l'insieme universo per una determinata categoria di oggetti come possono essere gli oggetti grafici.
Grafo pu\xF2 essere una classe Generica o Astratta che contiene tutti gli oggetti come Rettangolo, Cerchio, Punto, ecc.. Il predicato contiene sintetizza la definizione delle variabili di stato e dei metodi comuni a tutte le classi derivate da questa classe astratta.
abstract class Graphical extends Object {
protected Point lowerLeft; // lower left of bounding box
protected Point upperRight; // upper right of bounding box
.....
more instance variables
....
public void setPosition(Point ll, Point ur) {
lowerLeft = ll;
upperRight = ur;
}
abstract void drawMyself(); // abstract method
}
Interfacce (Interface)
La parola chiave
interaface
identifica un insieme di codice il cui fine \xE8 quello di definire un
contratto cio\xE8 una "descrizione informale del fine/significato" dei metodi. A tale scopo un'interfaccia, che \xE8 simile ad una classe, pu\xF2 contenere solo metodi,
astratti o costanti. Non pu\xF2 contenere "..costruttori, variabili statiche, variabili di istanza e metodi statici..." ( Vedi
Romani Universit\xE0 di Pisa )
Mentre una sottoclasse
estende una classe un'interfaccia pu\xF2
essere implementata da un metodo che necessariamente \xE8 pubblico.
Le relazioni extends e implements
Ogni classe estende (extends) una sola altra classe (Object se non specificata); Una interfaccia pu\xF2 estendere (extends) una o pi\xF9 interfacce:
public interface <Int> extends <Int1>,<Int2>, ...{
...
}
La gerarchia di ereditariet\xE0 singola delle classi e la gerarchia di ereditariet\xE0 multipla delle interfacce sono completamente disgiunte. Una classe pu\xF2 implementare (implements) una o pi\xF9 interfacce:
public class <nomeClasse> extends <nomeSuperClasse>
implements <Int1>, <Int2>, ..., <Intn> {
...
}
In questo caso
deve fornire una
realizzazione per tutti i metodi delle interfacce , , ... che implementa, nonch\xE9 per i metodi di eventuali super-interfacce da cui queste eredita.
Attraverso questo meccanismo il compito di scrittura dell'interfaccia e quello del codice che la utilizza possono svolgersi in modo autonomo. La modifica del codice di un'interfaccia se fatto nel rispetto del
contratto non richiede la modifica del codice che la utilizza.
Fine
--
RobertoBernetti - 19 Dec 2013