Newsgroup: it.comp.java
Titolo: generics e instanceof

ciao a tutti,
vi espongo subito il mio problema. ammettiamo di avere una gerarchia
di classi dichiarate così:
abstract public class A <T extends A>
public class B extends A<A>
public class C extends A<B>
public class D extends A<C>
All'interno della classe A c'è un metodo "x" protected, che poi viene
ridichiarato public in tutte le sottoclassi.
Ho implementato questa classe generica che deve gestire oggetti di
tipo B, C e D:
public class G <T extends A>.
All'interno della classe G devo utilizzare il metodo "x" di cui sopra.
Per richiamare il metodo corretto ho creato una serie di if di questo
tipo:
if(a instanceof B) {
     ((B)a).metodox(par1, par2);
}
if(a instanceof C) {
     ((C)a).metodox(par1, par2);
}
if(a instanceof D) {
     ((D)a).metodox(par1, par2);
}
il problema è che in questo modo ottengo un errore perché mi dice che
il metodo non è visibile.
qualcuno saprebbe dirmi come risolvere questo problema, considerando
che non posso rendere pubblico il metodo nella classe A?
grazie a tutti

Premetto che non ho mai creato classi con una gerarchia di questo
tipo!
Comunque, la clausola protected indica che il metodo è visibile
all'esterno della classe solo per le classi che appartengono allo
stesso package.
non è che per caso, volontà o errore le classi che ereditano sono in
un package differente?
Se si modifica il protected con public e dovrebbe andare tutto
il mio è un consiglio, non garantisco che funzioni.... Però lo spero
almeno riesci a proseguire con il tuo lavoro
Ciao Marco

'a' e' un'istanza di quale classe?
Certo che creare delle classi generiche e poi utilizzare un ciclo di if
annidati con degli instanceof e dei cast espliciti fa un po' rabbrividire...
Non si poteva fare in modo diverso? Cosa devi fare?

 un package differente?
Occhio, sbagli, stai parlando di friendly, *non* di protected.

 writes:
SS> Premetto che non ho mai creato classi con una gerarchia di questo
SS> tipo!
SS> Comunque, la clausola protected indica che il metodo è visibile
SS> all'esterno della classe solo per le classi che appartengono allo
SS> stesso package. 
Questa è la visibilità di default (senza specifiche). protected è
visibile dai membri del package _e_ dai discententi.
-- 
 /\           ___
/___/\_|_|\_|__|___Gian Uberto Lauri_____
  //--\| | \|  |   Integralista GNUslamico
\/                 e coltivatore diretto di Software
A Cesare avrei detto di scrivermi a 
fn...@rat.vg

 writes:
e> ciao a tutti, vi espongo subito il mio problema. ammettiamo di
e> avere una gerarchia di classi dichiarate così:
e> abstract public class A <T extends A> 
a> public class B extends A<A>
e> public class C extends A<B> 
a> public class D extends A<C>
e> All'interno della classe A c'è un metodo "x" protected, che poi
e> viene ridichiarato public in tutte le sottoclassi.
e> Ho implementato questa classe generica che deve gestire oggetti di
e> tipo B, C e D:
e> public class G <T extends A>.
e> All'interno della classe G devo utilizzare il metodo "x" di cui
e> sopra.  Per richiamare il metodo corretto ho creato una serie di if
e> di questo tipo:
Premetto che  con la 1.5 ed  i generics non  ci ho lavorato. Ma  G non
estende A, quindi,  a meno che non sia nello  stesso package, "non può
sapere che  il metodo esiste"  (protected rende il metodo  visibile al
package ed ai discendenti).
e> if(a instanceof B) { ((B)a).metodox(par1, par2);
e> }
e> if(a instanceof C) { ((C)a).metodox(par1, par2);
e> }
e> if(a instanceof D) { ((D)a).metodox(par1, par2);
e> }
Sicuro serva ? Una volta Java  usava il late binding, quindi è il tipo
dell'oggetto (non della variabile  che fa riferimento) a dettare quale
metodo è in uso. I generics portano l'early binding in Java ?


 metodo è in uso. I generics portano l'early binding in Java ?
In realtà i generics sono molto 'finti'. Evitano poco più di scrivere i
cast espliciti quando tiri fuori e dentro degli oggetti dalle
collezioni. 
Per dire a livello di VM sottostante, non vengono visti e il tutto viene
trasformato in termini di Object e cast.
-- 
blog:  
http://www.akropolix.net/rik0/blogs
 | Uccidete i filosofi,
site:  
http://www.akropolix.net/rik0/
      | tenetevi riso e
forum: 
http://www.akropolix.net/forum/
     | bacchette per voi.

 writes:
E'OF> Per dire a livello di VM sottostante, non vengono visti e il
E'OF> tutto viene trasformato in termini di Object e cast.
Come immaginavo, poco più di zucchero sintattico.
-- 
                                                    Gian
                                           Friends will be friends
                                              right to the end!

Innanzi tutto, grazie per le risposte.
Il codice che avevo scritto era corretto, solo che per una "svista"
non mi sono accorta di una cosa: il metodo in questione aveva lo
stesso nome in tutte le sottoclassi, ma uno dei parametri apparteneva
ad una gerarchia di classi parallela alla precedente.
Provo a spiegarmi meglio, nell'ipotesi che possa servire a qualcuno.
Nella classe A il metodo era dichiarato così:
protected String add(int par1, InfoA par2)
dove InfoA è una classe che contiene informazioni sugli oggetti di
tipo A.
Nelle sottoclassi B, C e D, il metodo era invece dichiarato
rispettivamente così:
protected String add(int par1, InfoB par2)
protected String add(int par1, InfoC par2)
protected String add(int par1, InfoD par2)
Quindi il casting funzionava correttamente, ma siccome io provavo a
passare alla funzione come secondo parametro un oggetto di tipo InfoA,
il compilatore cercava giustamente di chiamare il metodo add della
classe base A (che essendo protected non era accessibile da un altro
package).
Ora che mi sono accorta dell'errore sembra tutto ovvio e semplice, ma
è uno di quei casi in cui si prendono in considerazione tutte le
ipotesi, tranne quelle + logiche e immediate.
A parte questa riflessione personale, grazie a tutti per
l'interessamento, per l'aiuto ed i consigli.

 Come immaginavo, poco piů di zucchero sintattico.
Si, ma zucchero buono. Dopo tutto in un linguaggio che la mena come Java
con la type-safety e la tipizzazione statica dovere ricorrere a cast
ogni 3x2 per me č un pugno in un occhio.


 ipotesi, tranne quelle + logiche e immediate.
Beh, ti confesso che proprio semplice la struttura di classi non mi pare
nemmeno ora. E ribadisco quello che già ti hanno detto: sicura di avere
bisogno di qualcosa del genere?


 bisogno di qualcosa del genere?
Purtroppo non è una cosa che posso decidere io. La struttura è
utilizzata da un'applicazione che già esiste, io devo farne
un'estensione e sono obbligata ad utilizzare il codice esistente.
Se fosse dipeso da me, avrei evitato in tutti i modi complicazioni di
questo tipo :)

 un'estensione e sono obbligata ad utilizzare il codice esistente.
Direi che allora hai un ottimo motivo per proseguire così. :)
