edutecnica

Esercizio 9        

Definisci una opportuna gerarchia di classi per rappresentare valori numerici: tutte le classi devono implementare l'interfaccia numero (N) contenete i seguenti metodi
abstract double valore() che restituisce il valore associato a un dato numero,
abstract String stampa() che restituisce una stringa che descrive il valore.
Implementare poi le seguenti classi concrete:

la classe intero (I) che implementa numero e rappresenta un valore intero contiene oltre ai metodi ereditati i seguenti elementi:
una variabile di istanza valore:private int v che memorizza il valore intero associato all'oggetto
un costruttore pubblico ad un argomento valore che assegna il valore alla variabile di istanza valore.
Il metodo pubblico è divisibile: boolean estd(int v2) che restituisce true se il valore dell'oggetto this è divisibile con il valore associato a v2.
Il metodo pubblico getvalore: int getv() che restituisce il valore associato all'oggetto. il metodo ereditato String stampa() che restituisce una stringa del valore intero associato all'oggetto ed il metodo ereditato valore().

La classe frazione (F), implementa numero e rappresenta una frazione contiene oltre ai metodi ereditati anche i seguenti elementi due variabili di istanza
numeratore : private n(int) e
denominatore : d (int)
un costruttore pubblico con due argomenti:numeratore e denominatore;
il metodo pubblico boolean è-frazione-propria:boolean estfp() che non ha parametri e controlla se la frazione è una frazione propria (cioè rappresenta numeratore / denominatore ).
Il metodo void inversa() che non ha parametri che restituisce la frazione inversa della frazione rappresentata da this, ottenuta scambiando numeratore e denominatore. I metodi pubblici getn() e getd() che restituiscono numeratore e denominatore. Il metodo ereditato stampa() che restituisce una stringa nella forma (n/d). Il metodo ereditato valore() che restituisce il valore double associato alla frazione. La classe operazione (O) che implementa N e rappresenta una operazione aritmetica tra numeri scelta tra addizione, sottrazione, moltiplicazione e divisione; essa contiene oltre ad i metodi ereditati anche i seguenti elementi: tre variabili di istanza private: op1 (operando 1) op2 (operando 2) char op (operazione) che rappresentano i due operandi e l'operazione scelta tra + - * / ; deve esserci un costruttore pubblico con i tre argomenti op1,op2,op. i metodi pubblici getop1() getop2() e getop(). Il metodo ereditato stampa() che restituisce una una stringa nella forma op1 op op2 senza spazi il metodo ereditato valore che restituisce il valore double calcolato mediante l'espressione .


Il programma deve poter manipolare numeri interi attraverso la classe I; numeri razionali attraverso la classe F e le operazioni algebriche che possono intervenire fra questi tramite la classe (operazione) O.
L'interfaccia (numeri) N coordina le operazioni comuni di stampa restituendo il valore numerico di un numero o di una operazione tramite il metodo astratto :
double valore()
oppure restituendolo sotto forma di stringa tramite il metodo
String stampa()
Possiamo ideare uno schema di massima come il seguente:

Sono previsti dei metodi locali alle specifiche classi, ad esempio, per la classe I dei numeri interi deve esserci il metodo
boolean estd(int v2)
che controlla se il valore v dell'oggetto attuale (this) è divisibile per un altro valore v2 proveniente da un altro oggetto di classe I.
Per la classe I il metodo String stampa() deve restituire il valore rappresentato senza la notazione decimale al contrario del metodo double valore.

la classe F dei numeri razionali è dotata dei metodi
boolean estfp()
che controlla se na frazione è propria (numeratore < denominatore) void inversa() che inverte numeratore e denominatore ottenendo la frazione inversa. In questo caso il metodo String stampa() deve essere implementato in modo che sia restituita una stringa nella forma numeratore/denominatore.

La classe (operazione) O deve avere necessariamente due attributi op1 ed op2 per memorizzare gli operandi e un attributo char op per identificare l'operazione da eseguire fra loro. In questo caso il metodo String stampa() deve essere concretizzato in modo che sia restituita la stringa 'op1 op op2' senza spazi.

Una possibile versione del programma richiesto è la seguente:

class numeri{
public static void main(String[] args) {
I i1=new I(15);
I i2=new I(3);
F f1=new F(5,2);
System.out.println(i1.estd(i2.getv()));
System.out.println(i1.stampa());
System.out.println(i1.valore());
System.out.println(f1.stampa());
System.out.println(f1.estfp());
System.out.println(f1.valore());
f1.inversa();
System.out.println(f1.stampa());
System.out.println(f1.estfp());
System.out.println(f1.valore());
O opx=new O(i2,f1,'+');//3+5/2
System.out.println(opx.stampa());
System.out.println(opx.valore());
}//fine main
}//fine classe

interface N{
public String stampa();
public double valore();
} //fine interfaccia

class I implements N {
private int v;
I(int num) {v=num;} //costruttore
boolean estd(int v2){
   if(this.v%v2==0) return true;
   else return false;
} // fine estd
public int getv(){return v;}
public String stampa(){return Integer.toString(v);}
public double valore(){ return (double)v;}
}//fine I

class F implements N {
private int n;
private int d;
F(int num,int den) {n=num;d=den;} //costruttore
boolean estfp(){
  if(n < d) return true;
  else return false;
}//fine estfp
void inversa(){ int t; t=n;n=d;d=t; }//fine inversa
public int getn(){return n;}
public int getd(){return d;}
public String stampa(){return n+"/"+d;}
public double valore(){ return (double)n/d;}
}//fine F

class O implements N {
private N op1;
private N op2;
private char op;
O(N o1,N o2, char o) {op1=o1;op2=o2;op=o;} //costruttore
public double getop1(){return op1.valore();}
public double getop2(){return op2.valore();}
public char getop(){return op;}
public String stampa(){return op1.stampa()+op+op2.stampa();}
public double valore(){
switch(op){
   case '+':return op1.valore()+op2.valore();
   case '-':return op1.valore()-op2.valore();
   case '*':return op1.valore()*op2.valore();
   case '/':return op1.valore()-op2.valore();
   default: return 0;
}//fine switch
}//fine valore
}//fine O