Differences

This shows you the differences between two versions of the page.

Link to this comparison view

poo:breviare:breviar-06 [2020/11/10 09:16]
mihai.nan
poo:breviare:breviar-06 [2025/11/08 12:34] (current)
george.tudor1906
Line 1: Line 1:
 ====== Breviar 6 ====== ====== Breviar 6 ======
  
 +=== Clase abstracte și metode abstracte ===
  
 +== Introducere ==
 +
 +În proiectarea unei aplicații este adesea necesar să reprezentăm,​ cu ajutorul claselor, concepte **abstracte**,​ care nu pot fi instanțiate și care servesc doar la dezvoltarea ulterioară a unor clase ce descriu obiecte concrete.
 +
 +De exemplu, în pachetul **java.lang** există clasa abstractă **Number**, care modelează conceptul generic de „număr”. Într-un program nu avem însă nevoie de „numere generice”,​ ci de numere cu un anumit tip: întregi, reale etc.  ​
 +Clasa **Number** servește ca superclasă pentru clasele concrete **Byte**, **Double**, **Float**, **Integer**,​ **Long** și **Short**, care implementează obiecte pentru descrierea numerelor de un anumit tip.
 +
 +<note important>​
 +O clasă abstractă **nu poate fi instanțiată**. În locul ei vom utiliza **subclasele sale** care **nu sunt abstracte**.
 +</​note>​
 +
 +== Declararea claselor abstracte ==
 +
 +O clasă se declară ca fiind abstractă folosind cuvântul-cheie **abstract**.  ​
 +O clasă abstractă poate avea modificatorul **public**, accesul implicit fiind la nivel de pachet.  ​
 +Ea **nu poate** specifica modificatorul **final**, deoarece combinația `abstract final` este semnalată ca **eroare de compilare** (o clasă `final` nu poate fi extinsă, iar o clasă `abstract` trebuie extinsă).
 +
 +O clasă abstractă poate conține aceleași elemente membre ca o clasă obișnuită,​ dar și **metode abstracte** – adică metode **fără implementare efectivă**.
 +
 +<code java>
 +public abstract class Patrulater {
 +    class Point {
 +        int x, y;
 +        public Point(int x, int y) {
 +            this.x = x;
 +            this.y = y;
 +        }
 +    }
 +
 +    Point p1, p2, p3, p4;
 +
 +    // Metode abstracte
 +    abstract int calculPerimetru();​
 +    abstract double calculArie();​
 +}
 +</​code>​
 +
 +== Metode abstracte ==
 +
 +Spre deosebire de clasele obișnuite, care trebuie să furnizeze implementări pentru toate metodele declarate, o clasă abstractă poate conține **metode fără implementare**.  ​
 +Astfel de metode se numesc **metode abstracte** și pot apărea **doar** în clase abstracte.  ​
 +
 +În declararea unei metode abstracte se folosește cuvântul-cheie **abstract**.
 +
 +== Exemplu practic ==
 +
 +Paralelogramul,​ dreptunghiul,​ pătratul și rombul sunt figuri geometrice ce pot fi caracterizate prin patru puncte din plan.  ​
 +Pentru fiecare astfel de figură există o formulă prin care îi putem determina **aria**, știind coordonatele celor patru puncte sau alte date suplimentare.  ​
 +
 +Prin urmare, clasele care modelează aceste figuri pot fi derivate dintr-o clasă abstractă **Patrulater**.  ​
 +Deoarece pentru fiecare figură avem o formulă diferită de calcul al ariei, este normal ca **Patrulater** să conțină o metodă **calculArie()**.  ​
 +
 +Se pune însă problema implementării acestei metode în clasa de bază, deoarece fiecare patrulater concret are un mod propriu de calcul.  ​
 +Într-o astfel de situație, varianta corectă este ca metoda **calculArie()** să fie declarată **abstractă**,​ fără implementare.  ​
 +Implicit, clasa **Patrulater** devine una **abstractă**,​ deoarece conține o metodă abstractă.
 +
 +== Observații ==
 +
 +<note important>​
 +O clasă poate fi abstractă chiar dacă **nu conține** nicio metodă abstractă.
 +</​note>​
 +
 +<note important>​
 +Dacă o clasă conține **cel puțin o metodă abstractă**,​ atunci clasa trebuie **declarată abstractă**;​ în caz contrar, se semnalează o **eroare la compilare**.
 +</​note>​
 +
 +<note warning>
 +O subclasă a unei clase abstracte trebuie să **implementeze toate metodele abstracte** ale superclasei sale.  ​
 +Dacă nu o face, subclasa trebuie, la rândul ei, declarată **abstractă**.  ​
 +Nu pot fi instanțiate clase care conțin metode neimplementate!
 +</​note>​
 +
 +=== Interfețe ===
 +
 +== Introducere ==
 +
 +Interfețele duc conceptul de clasă abstractă cu un pas înainte, prin eliminarea oricăror implementări de metode, punând în practică unul dintre conceptele programării orientate pe obiecte: separarea modelului unui obiect (**interfața**) de implementarea sa.  ​
 +O interfață poate fi privită ca un protocol de comunicare între obiecte.
 +
 +== Definiție și comportament impus ==
 +
 +O interfață Java definește un set de metode, dar nu specifică nicio implementare pentru ele.  ​
 +O clasă care implementează o interfață trebuie, obligatoriu,​ să specifice implementări pentru **toate** metodele interfeței,​ supunându-se,​ așadar, unui anumit comportament.
 +
 +<note important>​
 +O interfață este o **colecție** de metode fără implementare și **declarații de constante**.
 +</​note>​
 +
 +== Acces și modificatori ==
 +
 +<note tip>
 +O interfață poate avea un singur modificator de acces, iar acesta este **public**.  ​
 +O interfață publică este accesibilă tuturor claselor, indiferent de pachetul din care fac parte; în lipsa lui, nivelul implicit de acces este la nivelul pachetului în care se află interfața.
 +</​note>​
 +
 +== Extinderea interfețelor ==
 +
 +O interfață poate extinde oricâte interfețe; acestea se numesc **superinterfețe**.
 +
 +== Cod sursă Java ==
 +
 +<code java>
 +interface Inf1 extends Comparable {
 +    public void method1();
 +}
 +
 +interface Inf2 extends Inf1 {
 +    public void method2();
 +}
 +
 +public class Test implements Inf2 {
 +    public void method2() {
 +        // Metoda din interfața Inf2
 +    }
 +
 +    public void method1() {
 +        // Metoda din interfața Inf1
 +    }
 +
 +    public int compareTo(Object o) {
 +        // Metoda din interfața Comparable
 +        return 0;
 +    }
 +}
 +</​code>​
 +
 +=== Compararea elementelor ===
 +
 +== Introducere ==
 +
 +Să presupunem că avem o listă, de tip **ArrayList**,​ cu elemente de tip **Student** și dorim să sortăm elementele din această listă după **media anilor**, presupunând că **Student** este o clasă ce conține printre membrii săi o variabilă ce reține media anilor.  ​
 +
 +Pentru realizarea acestui lucru există două posibilități,​ ce vor fi detaliate în continuare, folosind **Comparable** și **Comparator**.
 +
 +== Interfața Comparable ==
 +
 +Pentru a putea compara direct o instanță a unui tip (clasă definită de utilizator) cu o altă instanță, este necesar ca tipul respectiv să implementeze interfața **Comparable**.  ​
 +Această interfață conține o singură metodă, care returnează:​
 +  * un număr pozitiv – dacă instanța curentă este **mai mare** decât cea primită ca parametru;
 +  * 0 – dacă instanțele sunt **egale**;  ​
 +  * un număr negativ – dacă instanța curentă este **mai mică** decât cea primită ca parametru.
 +
 +<code java>
 +class Student implements Comparable {
 +    private String nume;
 +    private double medie;
 +
 +    public Student(String nume, double medie) {
 +        this.nume = nume;
 +        this.medie = medie;
 +    }
 +
 +    @Override
 +    public int compareTo(Object o) {
 +        Student obj = (Student) o;
 +        return (int)(this.medie - obj.medie);
 +    }
 +
 +    public String toString() {
 +        String result = nume + " " + medie;
 +        return result;
 +    }
 +
 +    public static void main(String args[]) {
 +        Vector v = new Vector();
 +        v.add(new Student("​Popescu",​ 10));
 +        v.add(new Student("​Ionescu",​ 9.75));
 +        v.add(new Student("​Popa",​ 9.80));
 +        Collections.sort(v);​
 +        System.out.println(v);​
 +    }
 +}
 +</​code>​
 +
 +== Interfața Comparator ==
 +
 +Interfața **Comparator** oferă o altă modalitate de comparare, separând logica de comparație de clasa comparată.  ​
 +Aceasta definește metoda **compare(Object o1, Object o2)**, care returnează un număr pozitiv, zero sau negativ în funcție de ordinea dorită între cele două obiecte.
 +
 +<code java>
 +class StudentComparator implements Comparator {
 +    @Override
 +    public int compare(Object o1, Object o2) {
 +        Student s1 = (Student) o1;
 +        Student s2 = (Student) o2;
 +
 +        if(s1.getMedie() > s2.getMedie()) {
 +            return 1;
 +        } else if(s1.getMedie() == s2.getMedie()) {
 +            return 0;
 +        } else {
 +            return -1;
 +        }
 +    }
 +}
 +
 +class Student {
 +    private String nume;
 +    private double medie;
 +
 +    public Student(String nume, double medie) {
 +        this.nume = nume;
 +        this.medie = medie;
 +    }
 +
 +    public String toString() {
 +        String result = nume + " " + medie;
 +        return result;
 +    }
 +
 +    public double getMedie() {
 +        return this.medie;
 +    }
 +
 +    public static void main(String args[]) {
 +        Vector v = new Vector();
 +        v.add(new Student("​Popescu",​ 10));
 +        v.add(new Student("​Ionescu",​ 9.75));
 +        v.add(new Student("​Popa",​ 9.80));
 +        Collections.sort(v,​ new StudentComparator());​
 +        System.out.println(v);​
 +    }
 +}
 +</​code>​
  
-<​HTML>​ 
-  <iframe src="​https://​docs.google.com/​file/​d/​1QdEIAyr8Ts4vwuizEgLORuLdRMB8iOK8/​preview"​ width="​640"​ height="​720"></​iframe>​ 
-  ​ 
-</​HTML>​ 
poo/breviare/breviar-06.1604992605.txt.gz · Last modified: 2020/11/10 09:16 by mihai.nan
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0