Quote:
Originariamente inviato da pepp1995
Obiettivo: avere un array di un certo Tipo ClassePadre MA "riempito" con oggetti di ClassiFiglie diverse.
Ho creato una ClassePadre: Figura in cui non faccio sostanzialmente nulla ed ho definito le varie ClassiDerivate di questa classe .
Ogni ClasseDerivata ha 1 unico metodo che è una stampa.
/*DEFINISCO la CLASSE MADRE*/
public class Figura{
}
/*DEFINISCO le CLASSI FIGLIE*/
class Triangolo extends Figura{
public void disegnaTriangolo()
{
System.out.println("disegno Triangolo");
}
}
class Cerchio extends Figura{
public void disegnaCerchio()
{
System.out.println("disegno cerchio");
}
}
class Quadrato extends Figura{
public void disegnaQuadrato()
{
System.out.println("disegno quadrato");
}
}
Il vettore voglio sia inizializzato, inizializzando " in modo random" i suoi elementi con oggetti delle tre classi figlie .
import java.util.Random; //importo la Classe Random
public class GeneratoreCasualeFigure{
//metodo
public Figura GeneraFigura()
{
Random rand=new Random();
Figura x=null;
switch(rand.nextInt(3))
{
case 0:
x= new Cerchio();
break;
case 1:
x= new Quadrato();
break;
case 2:
x= new Triangolo();
break;
}
return x;
}
}
Fin qui tutto funziona nella mainClass.
A questo punto , vorrei fare una stampa del vettore che "a seconda dell'oggetto\elemento del vettore da stampare, mi chiama il metodo() di stampa di quell'oggetto"
Quindo ho definito una classe: Test
public class Test{
public void stampaVettOggFiglie(Figura[] vet,int n )
{
for(int i=0; i<n; i++)
{
switch(vet[i].getClass().getName() ) //scelgo in base al tipoRefenziato
{
case "Triangolo":
vet[i].disegnaTriangolo();
break;
case "Quadrato":
vet[i].disegnaQuadrato();
break;
case "Cerchio":
vet[i].disegnaCerchio();
break;
}
}
}
public static void main(String[] args)
{
Figura[] A= new Figura[10];
GeneratoreCasualeFigure gen= new GeneratoreCasualeFigure();
for(int i=0; i<10; i++)
A[i] = gen.GeneraFigura();
//STAMPA VETTORE riempito con oggetti di classiFiglie diverse
Test x=new Test();
x.stampaVettOggFiglie(A,3);
}
}
PROBLEMA: ho un errore di compilazione, perché il compilatore cerca i tre metodi: disegnaTriangolo(), disegnaQuadrato() , disegnaCerchio() nella ClassePadre e vede che lì non ci sono.
Tuttavia, mi aspetterei che:
<<visto che "al momento dell'invocazione del metodo: stampaVettOggFiglie() ",gli elementi vet[i] sono stati inizializzati con le reference dei rispettivi oggetti--->
- nel momento in cui faccio : vet[i].disegnaTriangolo(); sto accedendo al metodo: disegnaTriangolo() dell' oggetto vet[i] della classe Triangolo
- nel momento in cui faccio : vet[i].disegnaQuadrato(); sto accedendo al metodo: disegnaQuadrato() dell' oggetto vet[i] della classe Quadrato
- nel momento in cui faccio : vet[i].disegnaCerchio(); sto accedendo al metodo: disegnaCerchio() dell' oggetto vet[i] della classe Cerchio >>
Perché non è così?
|
Ciao,
vet[i] è una reference a Figure, di conseguenza potrai invocare i soli metodi che costituiscono l'interfaccia di Figure.
Stai confondendo due concetti: un conto è il tipo concreto dell'oggetto che è referenziato - che può essere uno tra un triangolo, un cerchio e un quadrato - un'altra cosa è il tipo della referenza che punta ad esso e che definisce "ciò che puoi utilizzare".
Nel tuo caso devi eseguire un cast esplicito nella opportuna classe figlia, ad es:
case "Triangolo":
((Triangolo)vet[i]).disegnaTriangolo();
break;
o ancora meglio sfruttare in maniera più efficace interfacce e polimorfismo, per es (mantenendo quasi tutti i vecchi nomi):
/*DEFINISCO la CLASSE MADRE*/
public interface Figura {
void disegna();
}
/*DEFINISCO le CLASSI FIGLIE*/
class Triangolo implements Figura {
@Override
public void disegna() {
System.out.println("disegno Triangolo");
}
}
class Cerchio implements Figura { // TODO
}
class Quadrato implements Figura { // TODO
}
// test
public class Test {
private static final int SIZE = 10;
public static void stampaVettOggFiglie(Figura[] vet) {
for (Figura f : vet) {
f.disegna();
}
}
public static void main(String[] args) {
final Figura[] A = new Figura[SIZE];
final GeneratoreCasualeFigure gen = new GeneratoreCasualeFigure();
for (int i = 0; i < SIZE; i++) {
A[i] = gen.GeneraFigura();
}
//STAMPA VETTORE riempito con oggetti di classiFiglie diverse
stampaVettOggFiglie(A);
}
}