|
|
|
|
Strumenti |
12-08-2020, 15:13 | #1 |
Junior Member
Iscritto dal: Aug 2017
Messaggi: 4
|
[Java] codice non compila
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ì? |
13-08-2020, 11:24 | #2 | |
Member
Iscritto dal: Dec 2006
Messaggi: 33
|
Quote:
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); } } Ultima modifica di Lampo89 : 13-08-2020 alle 11:26. |
|
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 23:40.