PDA

View Full Version : [JAVA] Le interfaccie si perdono nei Vector


franksisca
13-12-2012, 17:35
esercizio semplice semplice...


una semplice classe che implementa una interfaccia

public class PallinoNome implements PincoPallino {
private String pallino;

public PallinoNome() {
this.setPallino("pallino");
}

@Override
public String getPallino() {
return this.pallino;
}

@Override
public void setPallino(String pallino) {
this.pallino = pallino;
}

}



la semplice interfaccia

public interface PincoPallino {
public String getPallino();

public void setPallino(String pallino);
}



e il main che "dovrebbe" funzionare

import java.util.Vector;

public class StarterClass {

public static void main(String[] args) {
Vector<PallinoNome> pinchipallini = new Vector<PallinoNome>();
aggiungiPallino(pinchipallini);
}

private static void aggiungiPallino(Vector<PincoPallino> pinchipallini) {
// TODO Auto-generated method stub
}
}


mi dà errore nella firma di aggiungiPallino, mi dice
The method aggiungiPallino(Vector<PincoPallino>) in the type StarterClass is not applicable for the arguments (Vector<PallinoNome>) StarterClass.java /testCase/src/proveStrane line 12 Java Problem


chi mi spiega il perchè si perde la generalizzazione dell'interfaccia? come potrei risolvere?

msangi
13-12-2012, 17:52
Il problema è dovuto al fatto che il metodo si aspetta un oggetto di tipo Vector<PincoPallino> mentre tu gli passi un oggetto di tipo Vector<PallinoNome>.

È vero che tra PincoPallino e PallinoNome c'è un rapporto di ereditarietà, ma questo non vale per i vettori che le utilizzano.
Generics were introduced in Java 5.0 to allow type-safe generic programming.
Unlike arrays, generic classes are neither covariant nor contravariant. For example, neither List<String> nor List<Object> is a subtype of the other.
http://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)#Java

franksisca
13-12-2012, 17:55
Ok, il problema l'avevo capito che era quello, solo che volevo una spiegazione più terra terra.

con le liste quindi dovrebbe funzionare?

msangi
13-12-2012, 17:59
No, anche con le liste avresti lo stesso problema.

Prova a dichiarare aggiungiPallino in questo modo
aggiungiPallino(Vector<? extends PincoPallino> pinchipallini)

In pratica usi una generic wildcard (http://docs.oracle.com/javase/tutorial/extra/generics/wildcards.html) in cui dici che il metodo deve accettare come parametro un vettore di qualcosa che estende PincoPallino.

franksisca
13-12-2012, 17:59
con questa implementazione è possibile bypassare il problema...
import java.util.Vector;

public class StarterClass {

public static void main(String[] args) {
Vector<PallinoNome> pinchipallini = new Vector<PallinoNome>();
aggiungiPallino(pinchipallini);
}

private static <E extends PincoPallino> void aggiungiPallino(
Vector<E> pinchipallini) {

}

}

msangi
13-12-2012, 18:05
È un altro modo per scrivere la soluzione che avevo postato io.

banryu79
13-12-2012, 18:09
con questa implementazione è possibile bypassare il problema...

A dire il vero non è che sia un "problema"... è proprio una conseguenza del modo in cui sono implementati i Generics in Java (type erasure).

Una risorsa esaustiva :D -> link (http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html#TOC)

franksisca
13-12-2012, 18:11
È un altro modo per scrivere la soluzione che avevo postato io.
si, l'abbiamo praticamente postata insieme, grazie mille
A dire il vero non è che sia un "problema"... è proprio una conseguenza del modo in cui sono implementati i Generics in Java (type erasure).

Una risorsa esaustiva :D -> link (http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html#TOC)

thanks a lot :D