1. Definire una classe Point, per rappresentare punti in uno spazio 2D. I punti sono descritti dalle coordinate x ed y, di tipo double. Il tipo di dato deve essere non modificabile, quindi il valore delle coordinate, una volta impostate nel costruttore, non deve essere più possibile cambiarlo. L'implementazione della classe non deve essere accessibile dall'esterno della classe (incapsulamento). Seguendo lo stile di Java, i metodi per leggere le coordinate di un punto dovrebbero chiamarsi getX e getY. Aggiungere anche il seguente metodo per stampare lo stato dell'oggetto: public void visualizza() { System.out.printf("Point[x=%d,y=%d]", x, y); } 2. Definire nella classe Point un metodo d'istanza double distance(Point p1) per calcolare la distanza tra il punto corrente e quello passato come parametro (suggerimento: per calcolare la radice quadrata si può utilizzare il metodo statico sqrt(x) della classe standard Math di Java). 3. La classe Shape rappresenta forme geometriche: public class Shape { private Point position; private boolean visible; public Shape(Point p) { position = p; visible = false; } public Shape(Point p, boolean vis) { position = p; visible = vis; } public double area() { return 0; } public Point getPosition() { return position; } public boolean isVisible() { return visible; } public void show() { visible = true; } public void hide() { visible = false; } public void move(Point p1) { position = position.add(p1); } } Il metodo area() di Shape calcola l'area di una figura. Definire un metodo add nella classe Point, in modo che l'implementazione del metodo move funzioni. 3. Perché, nella seguente definizione della sottoclasse Circle di Shape, il compilatore segnala un errore? Correggerlo. public class Circle extends Shape { private double radius; public Circle (Point p, double radius) { this.radius = radius; } } 4. Ridefinire il metodo area() in Circle. Definire un metodo public void move(double dx, double dy) in Circle, per spostare l'oggetto (come per il metodo move di Shape). 5. Definire la sottoclasse Rectangle di Shape, ridefinendo anche il metodo area(). Un rettangolo (classe Rectangle) è descritto dalla posizione del vertice in basso a sinistra, da una larghezza (width) e una altezza (height), e deve avere un costruttore public Rectangle(Point position, double width, double height) Fornire anche un costruttore public Rectangle(Point bottomleft, Point topright) { this(...); } i cui parametri descrivono un rettangolo specificando la posizione del vertice in basso a sinistra (bottomleft) e da quello in alto a destra (topright). Questo costruttore deve soltanto invocare il costruttore precedente con i parametri corretti. (Come prima, i campi della classe non devono essere accessibili dall'esterno della classe). Rectangle deve anche avere metodi per cambiare altezza e larghezza void setHeight(double v) void setWidth(double v) void resize(double newWidth, double newHeight) 4. Definire un metodo isSquare() per la classe Rectangle, che ritorna true se e solo se il rettangolo definito è in effetti un quadrato. 5. Definire una classe Square, sottoclasse di Rectangle. Che variabili d'istanza ha la classe Square? 6. Per i seguenti metodi di Square, il compilatore segnala errori? Se si, come si possono correggere? void setHeight(double v) { this.height = v; this.width = v; } void setWidth(double v) { this.height = v; this.width = v; } void resize(double newWidth, double newHeight) { if (newWidth == newHeight) super.resize(newWidth, newHeight); } 7. Supponiamo di cambiare l'implementazione della classe Rectangle, in modo che un rettangolo venga descritto internamente dalla sola variabile d'istanza Point topRight; che rappresenta il vertice in alto a destra del rettangolo (la variabile ereditata position rappresenta ancora il vertice in basso a sinistra). Quali metodi devono essere modificati? Quali altre classi è necessario modificare affinché tutto continui a funzionare? 8. Provare ad eseguire i frammenti di codice proposti in basso, utilizzando un metodo main in una classe Test. Che errori sono segnalati dal compilatore? Che errori avvengono a tempo di esecuzione? Che metodi vengono chiamati? Quali risultati vengono stampati? -------------------------------------------------------------------------------------------- Circle c = new Circle(new Point(3,3), 10); c.area(); -------------------------------------------------------------------------------------------- Shape c = new Circle(new Point(3,3), 10); c.area(); -------------------------------------------------------------------------------------------- Point p = new Point(3,4); Square sq = new Square(p, 10); System.out.println(sq.area()); Rectangle r = sq; System.out.println(r.area()); Shape s = r; System.out.println(s.area()); -------------------------------------------------------------------------------------------- Point p = new Point(3,4); Square sq = new Square(p, 10); Circle c = new Circle(p, 10); c.move(2, 2); c.getPosition().visualizza(); sq.getPosition().visualizza(); -------------------------------------------------------------------------------------------- Circle c = new Circle(new Point(3,3), 10); c.move(2,1); c.getPosition().visualizza(); -------------------------------------------------------------------------------------------- Circle c = new Circle(new Point(3,3), 10); Shape s = c; s.move(2,1); s.getPosition().visualizza(); -------------------------------------------------------------------------------------------- Circle c = new Circle(new Point(3,3), 10); Point p1 = null; c.move(p1); --------------------------------------------------------------------------------------------