Java Metode abstracte si exceptii abstract n n
Java – Metode abstracte si exceptii abstract n n clase metode Exceptii n n n descriere tratare generare
Modificatorul abstract n n n cuvantul cheie abstract poate fi utilizat ca si modificator aplicat unei clase sau metode; clasele abstracte nu pot fi instantiate, ele obliga la implementarea de subclase; o clasa se declara abstracta daca: n n n contine cel putin o metoda abstracta; mosteneste metode abstracte care nu sunt implementate; cand o clasa declara implementarea unei interfete dar nu implementeaza toate metodele din interfata. o metoda abstracta este o metoda declarata, dar neimplementata, adica nu are cod sau corp; prima subclasa concreta (neabstracta) trebuie sa implementeze toate metodele abstracte ale superclasei.
Exceptii n n orice program are un scop, exceptiile sunt situatii anormale in rularea lui; exceptiile trebuie prinse sau declarate si se reprezinta ca si obiecte; orice exceptie are un anumit tip; orice exceptie trebuie prinsa si tratata altfel programul se termina cu un mesaj de eroare; try { //cod care poate genera erori } catch(tipexceptie 1 ob) { //rutină pentru tratarea excepţiei 1 } catch(tipexceptie 2 ob) { //rutină pentru tratarea excepţiei 2 }. . . finally { //cod de executat înainte de terminarea // blocului try }
Aplicatia 1 n n n se pune problema scrierii unei aplicatii ce sa poate calcula, afisa si reprezenta grafic valorile unei functii date de programator si a primei derivate; algoritmul de calcul trebuie sa fie independent de functia aleasa de programator; din acest motiv clasa de baza ce implementeaza cerintele este una abstracta, functia devine cunoscuta, adica implementata, doar in subclasa concreta; calculul functiei sau a derivatei pot conduce la situatii exceptionale ce trebuie fie evitate fie tratate. clasa abstracta se numeste: Functie. A subclasele concrete se numesc: Functie 1 si Functie 2 partea de calcul si de afisare folosesc facilitatea de polimorfism in clasa de testare numita Test. Functii unde tabloul f. A (de elemente clasei de baza) stocheaza referinte la obiectele f 1 si f 2 (subclase concrete).
Aplicatia 1 / 1 Aceasta clasa abstracta declara functia abstracta de reprezentat cu linia ingrosata. Ea trebuie implementata in subclasele concrete derivate. public abstract class Functie. A { double a, b, h, x; int i, n; final int LY = 70; double[] xf; double[] yf; double[] dyf; public Functie. A(double a, double b, int n) { this. a = a; this. b = b; this. n = n; h = (b - a) / (n - 1); xf = new double[n]; yf = new double[n]; dyf = new double[n]; double min(double[] a) { double m = a[0]; for (int i = 1; i < a. length; ++i) if (a[i] < m) m = a[i]; return m; } double max(double[] a) { double m = a[0]; for (int i = 1; i < a. length; ++i) if (a[i] > m) m = a[i]; return m; } String functip(int p, char c, String in) { String aux = ""; calcul(); for (int i = 0; i < in. length(); ++i) if (i == p) aux += c; else aux += in. char. At(i); return aux; } public abstract double functie(double x); double functied 1(double x) { final double h = 0. 001; return (functie(x + h) - functie(x)) / h; } }
Aplicatia 1 / 2 Exceptiile pot sa apara in metoda, ingrosata, calcul() unde functia sau derivata pot sa nu exista in spatiul valorilor reale (double) double scale(double v, double vmin, double vmax) { return (v - vmin) / (vmax - vmin); } void calcul() { for (i = 1; i <= n; ++i) { x = a + (i - 1) * h; xf[i - 1] = x; yf[i - 1] = functie(x); dyf[i - 1] = functied 1(x); } } void afisare() { String tip; double minyf = min(yf); double maxyf = max(yf); double mindyf = min(dyf); double maxdyf = max(dyf); //minimul //maximul double ma double mi dintre cele 2 minime si dintre cele 2 maxime = (maxyf > maxdyf) ? maxyf : maxdyf; = (minyf < mindyf) ? minyf : mindyf; System. out. println("-----------------------"); System. out. println("| i | x | f(x) | fd 1(x) |"); System. out. println("-----------------------");
Aplicatia 1 / 3 for (i = 0; i < n; ++i) { int pos = (int)(scale(yf[i], mi, ma) * (LY - 1)); int pos 0 = (int)(scale(0. , mi, ma) * (LY - 1)); int posd = (int)(scale(dyf[i], mi, ma) * (LY - 1)); String tipinit = ""; for (int i = 1; i <= LY; ++i) tipinit += " "; //trasare axa Ox if (ma * mi < 0. ) tip = functip(pos 0, '|', tipinit); else tip = tipinit; //F pt. functie //D pt. derivata tip = functip(pos, 'F', tip); tip = functip(posd, 'D', tip); System. out. printf("| %3 d | %-+10. 6 f | %10. 6 f | %sn", i, xf[i], yf[i], dyf[i], tip); } System. out. println("-----------------------"); } }
Aplicatia 1 /4 Aici este dat codul subclaselor concrete si al celei de testare. public class Functie 1 extends Functie. A { public Functie 1(double a, double b, int n) { super(a, b, n); } @Override public double functie(double x) { return Math. sin(x)*Math. cos(x/2. ) ; } } public class Functie 2 extends Functie. A { public Functie 2(double a, double b, int n) { super(a, b, n); } @Override public double functie(double x) { return Math. sin(x)/x; } } public class Test. Functii { public static void main(String[] args) { Functie 1 f 1 = new Functie 1(-3. , 30); Functie 2 f 2 = new Functie 2(-7. , 30); Functie. A f. A[]= new Functie. A[2] ; f. A[0]=f 1; f. A[1]=f 2; for(Functie. A f: f. A) f. afisare(); } }
Aplicatia 1 / 5 Functie 1 f 1 = new Functie 1(-3. , 20); Functie 2 f 2 = new Functie 2(-7. , 20);
Aplicatia 1 / 6 Functie 1 f 1 = new Functie 1(-3. , 20); Functie 2 f 2 = new Functie 2(-7. , 15); In aceasta situatie f 2= sin(x)/x pentru x=0 nu se poate calcula. Aplicatia in locul valorilor normale afiseaza Na. N.
Aplicatia 1 / 7 daca codul de calcul este rescris sub forma: n void calcul() { double aux; for (i = 1; i <= n; ++i) { x = a + (i - 1) * h; xf[j - 1] = x; aux = functie(x); if (Double. is. Infinite(aux) || Double. is. Na. N(aux)) throw new Arithmetic. Exception("Probleme in evaluare la: " + x); yf[i - 1] = aux; dyf[i - 1] = functied 1(x); } } atunci se obtine o exceptie clara la in situatia de 0/0 si aplicatia se opreste. n
Aplicatia 1 / 8 n n n void Java implementeaza standardul IEEE 754 in lucrul cu numerele in virgula flotanta; conform acestui standard situatiile de 0/0, nr/0 sunt permise (nu sunt exceptii) si au valorile speciale de Na. N sau +/- Infinit motiv pentru } care utilizarea lui try cu catch nu rezolva aparitia acestor situatii; aceste cazuri trebuie testate in cod cu Double. is. Na. N() si Double. is. Infinite() apoi luate masurile necsare de corectie dupa cum se face in varianta de calcul() alaturata. calcul() { double aux; int j=1; for (i = 1; i <= n; ++i) { x = a + (i - 1) * h; xf[j - 1] = x; aux = functie(x); if (Double. is. Infinite(aux) || Double. is. Na. N(aux)) { --n; continue; } yf[j - 1] = aux; dyf[j - 1] = functied 1(x); ++j; }
Aplicatia 2 - try, catch, throws Aplicaţia ce urmează este formată din 2 clase Functie. java şi Test. Exceptii. java. Ea trebuie să evalueze valoarea unei funcţii F(x) definită în metoda F din clasa Functie. Această metodă generează excepţie de tipul Arithmetic. Exception. Excepţiile sunt generate deoarece pentru x = -2 expresia x/(x+2) nu se poate calcula, iar pentru x ∈ (4. 5, 5] radicalul are argumentul negativ. Metoda citeste_real() se foloseşte pentru a citi o valoare numerică reală (sau întreagă) de la tastatură. Reluarea citirii se face de cel mult 3 ori, după care aplicaţia se opreşte deoarece se generează o eroare ca nu este prinsă în aplicaţie. În această situaţie aplicaţie afişează starea stivei pentru a putea determina precis linia şi codul în care a apărut eroarea.
Aplicatia 2 /1 import java. util. *; public class Functie { public double F(double x) throws Arithmetic. Exception{ if (x < 1. ) { if (x == -2. ) throw new Arithmetic. Exception("Impartire cu 0"); return x/(x+2); } else if (x <= 5. ) { if (x > 4. 5) throw new Arithmetic. Exception("Argument radical negativ. "); return Math. sqrt(4. 5 -x); } else return Math. sin(x)/x; } public double citeste_real() throws Input. Mismatch. Exception { Scanner in = null; int contor. Err = 0; //contor erori, pt. 3 aplicatia se opreste. double x; while(true) { in = new Scanner(System. in); try { x = in. next. Double(); break; //daca nu sunt erori se iese din ciclu } catch (Input. Mismatch. Exception e) { ++contor. Err; System. out. printf("Eroare(%d) la citire, introduce o valoarea reala. n", contor. Err); if ( contor. Err == 3 ) throw new Input. Mismatch. Exception("*** Prea prost ca sa bage 1 numar real. ***"); } } return x; } }
Aplicatia 2 /2 public class Test. Exceptii { public static void main(String[] args) { Functie F 1 = new Functie(); double x 1, x 2; System. out. print("x 1="); x 1 = F 1. citeste_real(); System. out. print("x 2="); x 2 = F 1. citeste_real(); for(double x=x 1; x<=x 2; ++x) { try { System. out. printf("%6. 3 f %10. 7 fn", x, F 1. F(x)); } catch (Arithmetic. Exception e) { System. out. printf("%6. 3 f %sn", x, e); } } Se poate observa cum aplicaţia, deşi întâlneşte situaţii excepţionale, nu se termină brusc şi abrupt, ci ca urmare a tratării acestora, ajunge să se termine normal.
Aplicatia 3 – extindere clasa Exception Aplicaţia care urmează prezintă modul în care se extinde clasă Exception la clasa Exceptii. Aritmetice. public class Exceptii. Aritmetice extends Exception{ private String mesaj; public Exceptii. Aritmetice(String m) { super(m); mesaj = m; } public String to. String() { return "n. Exceptie: " + mesaj; } }
Aplicatia 3/1 public class Test. Ex 2 { public static int cat(int a, int b) throws Exceptii. Aritmetice { if (b == 0) throw new Exceptii. Aritmetice("Imparire cu zero!"); return a / b; } public static void main(String[] args) { int a, b, c; a=1; b=0; System. out. print(a + "/" + b ); try { c = (int)cat(a, b); System. out. println( "=" + c ); } catch (Exceptii. Aritmetice e) { System. out. println(e); } } }
Bibliografie n n http: //www. east. utcluj. ro/mb/mep/antal/downloads. html > Java: course, IDE (JDeveloper), JDK and JRE, JDeveloper labs. http: //docs. oracle. com/cd/E 18941_01/tutorials/jdtut_11 r 2_50/jdtut_11 r 2 _50. html > Getting Started With the JDeveloper IDE
- Slides: 18