D4rkAng3l
28-11-2008, 10:50
mmm, la professoressa ha trattato il concetto di copia hard in Java...mi dite se ho capito bene o se mi sfugge qualcosa?
Faccio un esempio pratico: ho una classe chiamata Rettangolo che mi definisce dei rettangoli e delle operazioni su di essi:
public class Rettangolo{
public Punto Pbl, Ptr; // Le variabili di istanza
Gli oggetti di tipo rettangolo sono identificati dalle variabili di istanza:
Pbl: il punto ineriore sinistro
Ptr: il punto superiore destro
in pratica definisco un rettangolo da 2 particolari dei suoi vertici diagonalmente opposti tra loro.
Ovviamente per funzionare la classe rettangolo ha bisogno del tipo di datp Punto definito proprio nella classe Punto:
public class Punto{
private double x,y; // Sono le variabili di istanza che rappresentano le coordinate del punto
/** Costruttore di oggetti istanza della classe Punto date le sue coordinate
@param x di tipo double: l'ascissa del punto da creare
@param y di tipo double: l'ordinata del punto da creare */
public Punto(double x, double y){
this.x = x; // La variabile di istanza x dell'oggetto da creare è ugale al valore del parametro x passato al costruttore
this.y = y; // La variabile di istanza y dell'oggetto da creare è ugale al valore del parametro y passato al costruttore
}
che definisce un oggetto di tipo punto mediante le sue coordinate x ed y.
(in entrambe le classi non inserisco tutti i metodi se no sarebbe lunghissimo)
Se gli oggetti di tipo Punto non sono modificabili (per esempio non posso traslare un punto lungo l'asse x o y)
allora per la classe Rettangolo potrò usare un costruttore banale come
public Retangolo(Punto P1, Punto P2){
this.Pbl = P1;
this.Ptr = P2;
}
che nelle variabili d'istanza di tipo Punto copia i riferimenti ai due punti e quindi il mio rettangolo sarà identificato da due oggetti di tipo Punto precedentemente creati (vabbè in questo caso ho anche semplificato assumendo che i punti passati fossero effettivamente i vertici inferiore sinistro e superiore destro).
Mettiamo ora caso che dentro la mia classe Punto ci voglio mettere due metodi: traslaLungoAsseX() e traslaLungoAsseY() che modificano l'oggetto punto cambiandone nel primo il valore dell'ascissa e nel secondo il valore dell'ordinata.
A questo punto avrei che le variabili di istanza della classe rettangolo (Punto Pbl, Ptr) sono 2 OGGETTI MODIFICABILI e sono nella cacca perchè se nel main traslo un punto che è anche vertice di un rettangolo ne consegue che ho modificato anche il rettangolo che avevo precedentemente creato e ciò potrebbe essere disastroso...allora se le variabili di istanza della classe Rettangolo sono oggetti modificabili devo usare un costruttore che fà la COPIA HARD. Cioè io al costruttore gli passo due oggetti di tipo Punto P1 e P2 e lui invece di assegnare ai vertici Pbl e Ptr il riferimento a P1 e P2 ne fà prima una copia edattribuisce ai miei vertici la copia...così se qualcuno modifica i punti di partenza nel main non va a smerdare anche il rettangolo costruito.
quindi avrò qualcosa del genere come nuovo costruttore sicuro:
public Rettangolo(Punto P1, Punto P2){
if(P1.getAscissa() < P2.getAscissa()){
if(P1.getOrdinata < P2.getOrdinata()){ // Se l'ascissa di P1 è minore dell'ascissa di P2 e se l'ordinata di P1 è minore dell'ordinata di P2
Pbl = new Punto(P1.getAscissa(), P1.getOrdinata());
Ptr = new Punto(P2.getAscissa(), P2.getOrdinata());
}
else{ // Se l'ascissa di P1 è minore dell'ascissa di P2 e se l'ordinata di P1 è maggiore dell'ordinata di P2
Pbl = new Punto(P1.getAscissa(), P2.getOrdinata());
Ptr = new Punto(P2.getAscissa(), P1.getOrdinata());
}
}
else{
if(P1.getOrdinata < P2.getOrdinata){ // Se l'ascissa di P1 è maggiore dell'ascissa di P2 e se l'ordinata di P1 è minore dell'ordinata di P2
Pbl = new Punto(P2.getAscissa, P1.getOrdinata);
Ptr = new Punto(P1.getAscissa, P2.getOrdinata):
}
else{ // Se l'ascissa di P1 è maggiore dell'ascissa di P2 e se l'ordinata di P1 è maggiore dell'ordinata di P2
Pbl = new Punto(P2.getAscissa(), P2.getOrdinata);
Ptr = new Punto(P1.getAscissa(), P1.getOrdinata);
}
}
(In questo caso ho gestito anche le eventualità che i 2 punti passati al costruttore non siano esattamente i vertici inferiore sinistro e superiore destro facendo in modo che se li ricavi e costruisca di conseguenza il rettangolo)
E' correto come ragionamento?
Grazie
Andrea
Faccio un esempio pratico: ho una classe chiamata Rettangolo che mi definisce dei rettangoli e delle operazioni su di essi:
public class Rettangolo{
public Punto Pbl, Ptr; // Le variabili di istanza
Gli oggetti di tipo rettangolo sono identificati dalle variabili di istanza:
Pbl: il punto ineriore sinistro
Ptr: il punto superiore destro
in pratica definisco un rettangolo da 2 particolari dei suoi vertici diagonalmente opposti tra loro.
Ovviamente per funzionare la classe rettangolo ha bisogno del tipo di datp Punto definito proprio nella classe Punto:
public class Punto{
private double x,y; // Sono le variabili di istanza che rappresentano le coordinate del punto
/** Costruttore di oggetti istanza della classe Punto date le sue coordinate
@param x di tipo double: l'ascissa del punto da creare
@param y di tipo double: l'ordinata del punto da creare */
public Punto(double x, double y){
this.x = x; // La variabile di istanza x dell'oggetto da creare è ugale al valore del parametro x passato al costruttore
this.y = y; // La variabile di istanza y dell'oggetto da creare è ugale al valore del parametro y passato al costruttore
}
che definisce un oggetto di tipo punto mediante le sue coordinate x ed y.
(in entrambe le classi non inserisco tutti i metodi se no sarebbe lunghissimo)
Se gli oggetti di tipo Punto non sono modificabili (per esempio non posso traslare un punto lungo l'asse x o y)
allora per la classe Rettangolo potrò usare un costruttore banale come
public Retangolo(Punto P1, Punto P2){
this.Pbl = P1;
this.Ptr = P2;
}
che nelle variabili d'istanza di tipo Punto copia i riferimenti ai due punti e quindi il mio rettangolo sarà identificato da due oggetti di tipo Punto precedentemente creati (vabbè in questo caso ho anche semplificato assumendo che i punti passati fossero effettivamente i vertici inferiore sinistro e superiore destro).
Mettiamo ora caso che dentro la mia classe Punto ci voglio mettere due metodi: traslaLungoAsseX() e traslaLungoAsseY() che modificano l'oggetto punto cambiandone nel primo il valore dell'ascissa e nel secondo il valore dell'ordinata.
A questo punto avrei che le variabili di istanza della classe rettangolo (Punto Pbl, Ptr) sono 2 OGGETTI MODIFICABILI e sono nella cacca perchè se nel main traslo un punto che è anche vertice di un rettangolo ne consegue che ho modificato anche il rettangolo che avevo precedentemente creato e ciò potrebbe essere disastroso...allora se le variabili di istanza della classe Rettangolo sono oggetti modificabili devo usare un costruttore che fà la COPIA HARD. Cioè io al costruttore gli passo due oggetti di tipo Punto P1 e P2 e lui invece di assegnare ai vertici Pbl e Ptr il riferimento a P1 e P2 ne fà prima una copia edattribuisce ai miei vertici la copia...così se qualcuno modifica i punti di partenza nel main non va a smerdare anche il rettangolo costruito.
quindi avrò qualcosa del genere come nuovo costruttore sicuro:
public Rettangolo(Punto P1, Punto P2){
if(P1.getAscissa() < P2.getAscissa()){
if(P1.getOrdinata < P2.getOrdinata()){ // Se l'ascissa di P1 è minore dell'ascissa di P2 e se l'ordinata di P1 è minore dell'ordinata di P2
Pbl = new Punto(P1.getAscissa(), P1.getOrdinata());
Ptr = new Punto(P2.getAscissa(), P2.getOrdinata());
}
else{ // Se l'ascissa di P1 è minore dell'ascissa di P2 e se l'ordinata di P1 è maggiore dell'ordinata di P2
Pbl = new Punto(P1.getAscissa(), P2.getOrdinata());
Ptr = new Punto(P2.getAscissa(), P1.getOrdinata());
}
}
else{
if(P1.getOrdinata < P2.getOrdinata){ // Se l'ascissa di P1 è maggiore dell'ascissa di P2 e se l'ordinata di P1 è minore dell'ordinata di P2
Pbl = new Punto(P2.getAscissa, P1.getOrdinata);
Ptr = new Punto(P1.getAscissa, P2.getOrdinata):
}
else{ // Se l'ascissa di P1 è maggiore dell'ascissa di P2 e se l'ordinata di P1 è maggiore dell'ordinata di P2
Pbl = new Punto(P2.getAscissa(), P2.getOrdinata);
Ptr = new Punto(P1.getAscissa(), P1.getOrdinata);
}
}
(In questo caso ho gestito anche le eventualità che i 2 punti passati al costruttore non siano esattamente i vertici inferiore sinistro e superiore destro facendo in modo che se li ricavi e costruisca di conseguenza il rettangolo)
E' correto come ragionamento?
Grazie
Andrea