Java, classi, tipi di dato astratto, metodi...

di il
3 risposte

Java, classi, tipi di dato astratto, metodi...

Premetto che sono alle prime armi con java e molto, ma molto arrugginita per quanto riguarda la programmazione, che non prendo più in mano da anni.
Per provare le classi, e la programmazione ad oggetti, ho pensato di definire una classe Razionale che mi permetta di definire e lavorare sui numeri razionali.
Ho creato i primi metodi: il costruttore dell'oggetto, un metodo per semplificare il numero razionale, dividendo numeratore e denominatore per il MCD di essi ed uno per stamparlo.
Fin qui tutto bene (posto il codice che ho scritto, e nel quale devo ancora inserire il controllo che il denom sia !=0):
public class Razionale {

	/**
	 * @param args
	 */
	 boolean segno; // true positivo, false negativo
	 int num, denom;
	public Razionale (int num,int denom){
		
		this.segno=(num*denom>=0);
		this.num=Math.abs(num);
                this.denom=Math.abs(denom); 
	}
	private int MCD (int a, int b) {
		if (a<b)
			return MCD (b,a);
		else if (b== 0)
				return a;
		     else
			    return MCD (a-b, b);
	}
	private int mcm (int a, int b) {
		return a*b/MCD(a,b);
	}
	
	public void semplifica () {
		int div;
		div = MCD(this.num,this.denom);
		this.num=this.num/div;
		this.denom=this.denom/div;
				
	}
	public void stampa(){
		if (this.segno) 
			System.out.print('+');
		else
			System.out.print('-');
		System.out.print (this.num);
		System.out.print('/');
		System.out.println(this.denom);
	}
Come dicevo, fin qui tutto bene, perché i metodi che ho scritto sono unari, ossia lavorano solo su unico razionale.
Vorrei ora passare a definire metodi binari, ossia che lavorano su due razionali (ad esempio la somma e il prodotto).
Quello che mi piacerebbe è costruire un metodo che prenda in input due razionali e ne calcoli la somma (o il prodotto). Però... mi pare che ci sia una asimmetria tra i due operandi: uno deve essere il proprietario del metodo, l'altro un secondo razionale, quindi il metodo somma dovrebbe essere del tipo
public void somma (Razionale b) {
...
...
}
e poi richiamato, nel main con:

Razionale a=new Razionale(...,...);
Razionale b=new Razionale(...,...);
...
...
a.somma(b);
Non mi piace. Non mi piace questa asimmetria fra i due operandi. Mi piacerebbe poter scrivere

.... somma (a,b)....
C'è qualche cosa di più elegante che non ho ancora studiato?

3 Risposte

  • Re: Java, classi, tipi di dato astratto, metodi...

    Rieccomi qui.
    Ho modificato un po' il codice (ho eliminato il booleano per il segno, ed ho al suo posto inserito un int che vale -1 se il segno della frazione è negativo, 1 in caso contrario... risulta più semplice la somma.
    Ho poi scritto due metodi per somma e prodotto, ed uno per il reciproco.
    Riposto il codice modificato.
    public class Razionale {
    
    	/**
    	 * @param args
    	 */
    	
    	 int sgn, num, denom;
    	public Razionale (int num,int denom){
    		
    		this.sgn=num*denom>=0?1:-1; // il segno è memorizzato a parte e vale -1 se la frazione è <0, +1 altrimenti
    		this.num=Math.abs(num);     // Numeratore e denominatore sono 
            this.denom=Math.abs(denom); // senza segno
    	}
    	public Razionale(){
    		
    	}
    	private int MCD (int a, int b) {
    		if (a<b)
    			return MCD (b,a);
    		else if (b== 0)
    				return a;
    		     else
    			    return MCD (a-b, b);
    	}
    	private int mcm (int a, int b) {
    		return a*b/MCD(a,b);
    	}
    	
    	public void semplifica() {
    		int div;
    				div = MCD(this.num,this.denom);
    		
    		this.num=this.num/div;
    		this.denom=this.denom/div;
    		
    				
    	}
    	public void stampa(){
    		char segno;
    		segno=(this.sgn<0)?'-':'+'; 
    		System.out.println(segno +Integer.toString(this.num)+'/'+Integer.toString(this.denom));
    	}	
    	
    	public Razionale reciproco (){
    		return new Razionale(this.sgn*this.denom,this.num);
    	}
    	public Razionale somma (Razionale b){
    		int n,d; // per contenere il numeratore e il denominatore della somma
    		d=mcm(this.denom,b.denom);
    		n=this.sgn * this.num* (d/this.denom) + b.sgn*b.num*(d/b.denom);
    		Razionale temp= new Razionale(n,d);
    		temp.semplifica();
    		return temp;
    	}
    	public Razionale prodotto (Razionale b) {
    		Razionale temp =new Razionale();
    		temp.sgn=this.sgn*b.sgn;
    		temp.num=this.num*b.num;
    		temp.denom=this.denom*b.denom;
    		temp.semplifica();
    		return temp;
    	}
    Resta la mia domanda di prima... non è possibile rendere 'simmetrici' i metodi binari (non mi piace la diversità che esiste, sintatticamente parlando, tra i due operatori della somma e del prodotto).

    Ho anche un'altra domanda, ma la faccio dopo, o in un altro post, per non farne troppe insieme.
  • Re: Java, classi, tipi di dato astratto, metodi...

    Nella programmazione a oggetti è normale che le cose siano "sbilanciate" perché i metodi in generale si applicano sugli oggetti: per cui è normale che l'istruzione "a.somma(b)" significhi "somma l'oggetto b sull'oggetto a".

    Ciò che chiedi è un qualcosa che non ha a che fare col singolo oggetto, in quanto l'operazione è legata alla classe (al mondo dei razionali) piuttosto che alla singola istanza. Per cui puoi modificare la classe Razionale in questo modo:
    
    public class Razionale {
        ...
    
        public static Razionale somma(Razionale a, Razionale b){
            ...
        }
    }
    
    Ed utilizzarlo in questo modo
    
    Razionale a = new Razionale(...);
    Razionale b = new Razionale(...);
    
    Razionale risultato = Razionale.somma(a,b);
    
  • Re: Java, classi, tipi di dato astratto, metodi...

    Ok!
    Grazie tantissimo!
Devi accedere o registrarti per scrivere nel forum
3 risposte