Cosa chiede la verifica
Le verifiche (TechCorp, SuperDelta, SportLife) sono la stessa identica struttura con storie diverse. Mettono insieme tutto: gerarchia di classi, un'interfaccia come tipo comune, una classe con validazione nel costruttore, il polimorfismo e la scrittura di un file CSV. Schema generale:
- [4.0] interfaccia (Pagabile/Misurabile) + superclasse + 3 sottoclassi che calcolano l'importo in modo diverso.
- [2.5] una classe esterna (Fattura/CertificatoMedico) con costruttore validato (quantita > 0).
- [2.5] un Gestore che scorre un array del tipo-interfaccia e scrive il CSV (separatore ;).
- [1.0] lettura di un file di input e creazione dinamica degli oggetti.
Interfaccia, gerarchia, validazione
Definiamo l'interfaccia come tipo comune e la superclasse astratta. Ogni sottoclasse fa l'override di getImporto() con la sua formula.
interface Pagabile { double getImporto(); String getTipo(); String getId(); } abstract class Impiegato implements Pagabile { protected String nome, cognome, codiceFiscale; Impiegato(String n, String c, String cf) { nome = n; cognome = c; codiceFiscale = cf; } public String getId() { return nome + " " + cognome; } }
class ImpiegatoSalariato extends Impiegato { private double stipendio; ImpiegatoSalariato(String n,String c,String cf,double s) { super(n,c,cf); stipendio = s; } public double getImporto() { return stipendio; } public String getTipo() { return "ImpiegatoSalariato"; } } class ImpiegatoOrario extends Impiegato { private double paga; private int ore; ImpiegatoOrario(String n,String c,String cf,double p,int o) { super(n,c,cf); paga = p; ore = o; } public double getImporto() { return paga * ore; } public String getTipo() { return "ImpiegatoOrario"; } } class ImpiegatoAProvvigione extends Impiegato { private double base, vendite, perc; ImpiegatoAProvvigione(String n,String c,String cf, double b,double v,double p) { super(n,c,cf); base=b; vendite=v; perc=p; } public double getImporto() { return base + vendite * perc / 100; } public String getTipo() { return "ImpiegatoAProvvigione"; } }
La classe esterna con validazione nel costruttore (il punto che fa perdere voti se dimenticato):
class Fattura implements Pagabile { private String numero, descrizione; private double prezzoPerUnita; private int quantita; private boolean valida = true; Fattura(String num, String desc, int q, double prezzo) { if (q <= 0) { // validazione richiesta dalla traccia System.out.println("Errore: quantita non valida " + num); valida = false; return; } numero=num; descrizione=desc; quantita=q; prezzoPerUnita=prezzo; } public boolean isValida() { return valida; } public double getImporto() { return prezzoPerUnita * quantita; } public String getTipo() { return "Fattura"; } public String getId() { return numero + " - " + descrizione; } }
Gestore, polimorfismo e CSV
Il gestore scorre l'array Pagabile[] in modo polimorfico e scrive il CSV. Il main legge prima il file di input, crea gli oggetti (con validazione) e mette tutto insieme.
import java.io.*; class GestorePagamenti { private Pagabile[] elementi; GestorePagamenti(Pagabile[] e) { elementi = e; } public void scriviCSV(String nomeFile) throws IOException { PrintWriter out = new PrintWriter(nomeFile); out.println("TipoEntita;Identificativo;ImportoDovuto"); for (Pagabile p : elementi) // polimorfismo: ogni getImporto() e' il suo out.println(p.getTipo() + ";" + p.getId() + ";" + String.format("%.2f", p.getImporto())); out.close(); } }
import java.io.*; import java.util.*; public class Main { public static void main(String[] a) throws IOException { ArrayList<Pagabile> lista = new ArrayList<>(); // impiegati lista.add(new ImpiegatoSalariato("Mario","Rossi","RSSMRA", 2500)); lista.add(new ImpiegatoOrario("Luigi","Verdi","VRDLGU", 16, 80)); // lettura file di input Scanner in = new Scanner(new File("fatture_input.txt")); while (in.hasNextLine()) { String[] c = in.nextLine().split(";"); Fattura f = new Fattura(c[0], c[1], Integer.parseInt(c[2]), Double.parseDouble(c[3])); if (f.isValida()) lista.add(f); // solo se la validazione passa } in.close(); // scrittura CSV finale Pagabile[] arr = lista.toArray(new Pagabile[0]); new GestorePagamenti(arr).scriviCSV("pagamenti.csv"); } }
Spiegazione punto per punto
1–2. L'interfaccia Pagabile e' il tipo comune; la superclasse astratta raccoglie i dati condivisi; le tre sottoclassi fanno override di getImporto() con la loro formula. La validazione (quantita > 0) sta nel costruttore di Fattura e blocca gli oggetti non validi.
3. GestorePagamenti non sa quali classi ci siano nell'array: chiama getImporto() e il polimorfismo sceglie la versione giusta. Il CSV usa ; e l'intestazione richiesta.
4. Prima della scrittura, il main legge fatture_input.txt, spezza ogni riga con split(";"), crea le Fatture e le aggiunge solo se valide. Per SuperDelta cambia Fornitore; per SportLife diventano Misurabile e CertificatoMedico: la struttura non cambia.
La simulazione
Stampa la traccia e svolgila in 90 minuti senza guardare la soluzione. Poi confronta con la Lezione 10. Il PDF contiene anche le soluzioni in coda.