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