Newsgroup: it.comp.java
Titolo: Esercizio Java

Ciao, vi propongo questo piccolo esercizio di Java che fa parte di un 
esame di paradigmi di programmazione, per molti sarà banale ma io non 
riesco a venirne a capo.
interface A {
int val=1;
int foo (int x);
}
interface B {
int z=1;
int fie (int y);
}
Class C implements A,B {
int val = 2;
int x = 2;
int n = 0;
public int foo (int x) { return x+val+n;}
public int fie (int y) { return z+val+n;}
}
class D extends C {
int val = 3;
int z = 3;
int n = 3;
public int foo (int x){return x+val+n}
public int fie (int y){return z+val+n;}
Si consideri ora il seguente frammento di programma:
int u, v, w, z;
A a;
B b;
D d = new D();
a = d;
b = d;
System.out.println(u = a.foo(1));
System.out.println(v = b.fie(1));
System.out.println(w = d.foo(1));
System.out.println(z = d.fie(1));
Cosa stampa ?

 Cosa stampa ?
7
9
7
9
Considera che: 
-tutti  i riferimenti sono di tipo D 
-Se in un punto ci sono due variabili con lo stesso nome, il valore è quello
della variabile dichiarata più vicino a dove ti trovi. Esempio: 
class D extends C {
int val = 3;
int z = 3;
int n = 3;
public int foo (int x){return x+val+n}
}
c'é una variabile di nome val dichiarata in D, in C ed in A. Tutte sono
pubbliche quindi accessibili al metodo foo(). Ma il metodo foo() è in D
quindi il valore di val è 3 cioé quello dichiarato in D. Se ci fosse un val
anche in foo, ad esempio:
public int foo(int c) {
  int val = -1;
  return x+val+n;
}
val assumerebbe il valore -1 essendo dichiarata nel blocco più interno e
vicino a chi la usa. Chiaro?
- Un discorso analogo vale per i metodi. Quando c'é overriding viene
invocato quello della classe più vicina a quella del riferimento che hai.
In questo codice:
D d = new D();
a = d;
b = d;
a.foo(1) e d.foo(1) sono equivalenti. Non importa che tu acceda all'oggetto
con un riferimento di tipo A, viene sempre invocato il foo della classe più
specifica che in questo caso è D.
A potrebbe confonderti perché è un'interfaccia, quindi è chiaro che l'unica
implementazione di foo() è quella in D. Ma lo stesso si verificherebbe se
avessi:
D d = new D();
C c = d;
c.foo()
viene sempre chiamato il foo() di D.
Per concludere risolvo l'esercizio passo passo per il primo metodo:
int u, v, w, z;
A a;
B b;
D d = new D();
a = d;
b = d;
System.out.println(u = a.foo(1));
viene stampato il valore di u, cioé quello restituito da a.foo(1). Chiediti,
qual'é il metodo invocato con a.foo()? Prima cosa da sapere: di che tipo è
veramente a? Per saperlo bisogna trovare l'invocazione del costruttore
dell'oggetto che è stato assegnato ad a.
Allora leggi qui:
a = d;
e dici: ok, a in realtà d. Di che tipo è d?
Leggi qua:
D d = new D(); 
e dici bene: è di tipo D.
Ricordati: conta il costruttore non il tipo del riferimento.
Andiamo avanti.
D ha l'implementazione di un metodo foo(int )? Si, ottimo, non serve
guardare la superclasse.Attenzione: è importante che coincidano il nome ed
il tipo di ogni parametro. Altrimenti, anche se ha lo stesso nome, non è lo
stesso metodo.
concentriamoci su questo metodo:
class D extends C {
int val = 3;
int z = 3;
int n = 3;
public int foo (int x){return x+val+n}
}
restituisce x + val + n
qual'é l'x più vicino? Il parametro del metodo. Che valore ha? Quello
passato nel programma cioé qui:
System.out.println(u = a.foo(1));
ok, x = 1.
quel'é il val più vicino? La variabile di istanza dicharata in D. Se questa
non ci fosse sarebbe quella dichiarata in C. Ma c'é quindi
val = 3;
e per quanto riguarda n? Come per val, quindi
n = 3
allora il metodo restituisce 1+3+3 = 7
Dovrei essere stato esauriente :) Penso che dopo questa spiegazione, e se
non ho fatto casino da qualche parte non avrai più problemi con questi
esercizi ;)
Ciao
-- 
chi sono e soprattutto chi non sono:
http://www.ilnomedeldominio.it
un piccolo programma per studenti universitari:
http://inutility.ilnomedeldominio.it/imsv/