Cognome e Nome: Numero di Matricola: Spazio riservato alla correzione 1 2 3 4 5 6 totale /5 /10 /10 /30 /25 /20 /100 Non usare altri fogli, usare solo lo spazio sottostante. Fogli differenti da questo non saranno presi in considerazione per la correzione. Non è consentito usare libri o appunti! 1. [5 punti] Considerate il frammento di codice seguente: public class T public void m(final int x, int y) int a; final int b; class C implements I public void f( ) int c; private int t; Indicate a quali variabili può accedere il metodo f e giustificate la risposta. Soluzione: la classe interna C può accedere alle variabili istanza definite nell ambito di visibilità della classe T senza alcuna restrizione, ma può accedere a variabili locali solo se sono state dichiarate final. Quindi il metodo f può accedere alle variabili x, b e t. Pag. 1
2. [10 punti] Sia B una classe e sia A una classe che implementa l interfaccia I. Indicare quali dei seguenti assegnamenti sono leciti e giustificare la risposta. A a = new A(); B b = new B(); I i1 = a; //primo assegnamento I i2 = b; //secondo assegnamento a = (I)b; //terzo assegnamento a = i1; //quarto assegnamento a = (A)i1; //quinto assegnamento Soluzione: Gli assegnamenti corretti sono il primo e il quinto. Infatti la classe A implementa l interfaccia I, quindi la conversione dal tipo A al tipo dell interfaccia nel primo assegnamento è lecita. Nell assegnamento 5, il tipo interfaccia viene convertito al tipo originario mediante un cast. L assegnamento 2 è scorretto perché la classe B non implementa l interfaccia I. L assegnamento 3 è scorretto perché non è possibile usare il cast per convertire dal tipo B al tipo dell interfaccia. L assegnamento 4 è scorretto: per convertire dal tipo interfaccia al tipo originario A è necessario un cast, come avviene nell assegnamento 5. Pag. 2
3. [10 punti] Descrivere a cosa serve la parola chiave super e mostrarne l utilizzo con un breve esempio di codice. Soluzione: La parola chiave super viene utilizzata per: invocare il costruttore della superclasse, e.g.,. super(initialbalance); invocare un metodo della superclasse, e.g. super.deposit(amount); /** Un conto corrente che addebita commissioni per ogni transazione. */ public class CheckingAccount extends BankAccount /** Costruisce un conto corrente con un saldo assegnato. @param initialbalance il saldo iniziale */ public CheckingAccount(double initialbalance) // chiama il costruttore della superclasse super(initialbalance); // inizializza il conteggio delle transazioni transactioncount = 0; //metodo sovrascritto public void deposit(double amount) transactioncount++; //chiama il metodo deposit della superclasse super.deposit(amount); //metodo sovrascritto public void withdraw(double amount) transactioncount++; // chiama il metodo withdraw della superclasse super.withdraw(amount); //metodo nuovo public void deductfees() if (transactioncount > FREE_TRANSACTIONS) double fees = TRANSACTION_FEE * (transactioncount FREE_TRANSACTIONS); //chiama il metodo withdraw della superclasse super.withdraw(fees); transactioncount = 0; private int transactioncount; private static final int FREE_TRANSACTIONS = 3; private static final double TRANSACTION_FEE = 2.0; Pag. 3
4. [30 punti] Scrivere un applet che consenta all utente di specificare un cerchio con due pressioni del pulsante del mouse, la prima per indicare la posizione del centro e la seconda per indicare un punto sulla circonferenza. Quando l utente preme per la prima volta, disegnate un cerchietto per indicare il centro, quando preme per la seconda volta, disegnate il cerchio. Suggerimento: nel gestore degli eventi del mouse dovete tenere traccia del fatto che sia già stato ricevuto il punto che rappresenta il centro in un evento precedente. I punti devono essere istanze della classe Point2D.Double import java.awt.graphics2d; import java.awt.geom.ellipse2d; import java.awt.geom.point2d; public class Cerchio /** Costruisce un oggetto Cerchio @param duepunti l array di punti specificati dall utente */ public Cerchio(Point2D.Double[] duepunti) punti = duepunti; /** Disegna il cerchio, dati due punti Il primo punto è il centro, il secondo è un qualsiasi punto sulla circonferenza. @param g2 il contesto grafico */ public void disegna(graphics2d g2) // Calcola il centro del cerchio double x = punti[0].getx(); double y = punti[0].gety(); Point2D.Double centro = new Point2D.Double(x, y); // Calcola il raggio del cerchio double raggio = Math.sqrt(Math.pow(centro.getX() - punti[1].getx(), 2) + Math.pow(centro.getY() - punti[1].gety(), 2)); // Costruisce il cerchio e lo disegna Ellipse2D.Double cerchio = new Ellipse2D.Double(centro.getX() - raggio, centro.gety() - raggio, 2 * raggio, 2 * raggio); g2.draw(cerchio); private Point2D.Double[] punti; Pag. 4
import java.applet.applet; import java.awt.graphics; import java.awt.graphics2d; import java.awt.event.mouseadapter; import java.awt.event.mouseevent; import java.awt.geom.ellipse2d; import java.awt.geom.point2d; public class CerchioApplet extends Applet public CerchioApplet() clicks = 0; punti = new Point2D.Double[MAX_CLICKS]; // classe interna per l ascoltatore class MousePressListener extends MouseAdapter public void mousepressed(mouseevent event) if (clicks >= MAX_CLICKS) return; int mousex = event.getx(); int mousey = event.gety(); punti[clicks] = new Point2D.Double(mouseX, mousey); clicks++; repaint(); // aggiunge l ascoltatore di eventi alla finestra dell applet MousePressListener listener = new MousePressListener(); addmouselistener(listener); public void paint(graphics g) Graphics2D g2 = (Graphics2D)g; if (clicks < MAX_CLICKS) for (int i = 0; i < clicks; i++) double x = punti[i].getx(); double y = punti[i].gety(); Ellipse2D.Double cerchietto = new Ellipse2D.Double(x - RADIUS, y - RADIUS, 2 * RADIUS, 2 * RADIUS); g2.draw(cerchietto); else Cerchio c = new Cerchio(punti); c.disegna(g2); private int clicks; private Point2D.Double[] punti; private final int MAX_CLICKS = 2; final double RADIUS = 2; Pag. 5
5. [25 punti] Definire una superclasse astratta FigureGeometriche e tre sottoclassi Cerchio, Rettangolo e TriangoloIsoscele. Per ciascuna classe, definire le variabili istanza per le dimensioni che caratterizzano il tipo di figura, il costruttore per la creazione di un istanza di ciascuna figura date le dimensioni, e due metodi getarea() e getperimetro(), che restituiscono rispettivamente l area e il perimetro della figura. public abstract class FigureGeometriche public abstract double getarea(); public abstract double getperimetro(); public class TriangoloIsoscele extends FigureGeometriche public TriangoloIsoscele(double b, double h) base = b; altezza = h; public double getarea() return base * altezza /2 ; public double getperimetro() double mezzabase = base/2; double lato = Math.sqrt(mezzabase * mezzabase + altezza * altezza); return 2*lato + base; private double base; private double altezza; public class Cerchio extends FigureGeometriche public Cerchio(double r) raggio = r; public double getarea() return raggio * raggio * Math.PI; public double getperimetro() return 2 * raggio * Math.PI; private double raggio; Pag. 6
public class Rettangolo extends FigureGeometriche public Rettangolo(double b, double h) base = b; altezza = h; public double getarea() return base * altezza; public double getperimetro() return 2 * base + 2 * altezza; private double base; private double altezza; Pag. 7
6. [20 punti] Scrivere un programma di Test per le classi create nell esercizio precedente. Creare un array di figure geometriche, contenente cinque oggetti per ognuna delle classi create, assegnando a ciascuna dimensione un valore casuale. Stampare la somma delle aree e dei perimetri di tutte le figure presenti nell array..public class Test public static void main(string [] args) FigureGeometriche [] fg = new FigureGeometriche[15]; for (int i = 0; i < 15; i++) if( i<5) fg[i] = new Cerchio(Math.random()*10); else if (i < 10) fg[i] = new TriangoloIsoscele(Math.random()*10,Math.random()*10); else fg[i] = new Rettangolo(Math.random()*10, Math.random()*10); double areatotale = 0; double perimetrototale = 0; for (int i = 0; i < 15; i++) areatotale += fg[i].getarea(); perimetrototale += fg[i].getperimetro(); System.out.println( Area totale: + areatotale); System.out.println( Perimetro totale: + perimetrototale); Pag. 8