Differences

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

Link to this comparison view

poo-ca-cd:laboratoare:clase-abstracte-interfete [2020/10/03 16:34]
mconstantin1412 [Obiective]
poo-ca-cd:laboratoare:clase-abstracte-interfete [2023/11/05 20:16] (current)
eduard.marin [Exerciţii]
Line 1: Line 1:
-===== Clase abstracte și interfețe ​=====+===== Laboratorul 5: Abstractizare ​===== 
 + 
 +**Video introductiv:​** [[https://​www.youtube.com/​watch?​v=R9KO-GHbNUA|link]]
  
 ==== Obiective ==== ==== Obiective ====
-Scopul acestui laborator este prezentarea conceptelor de **interfață** și de **clasă abstractă** și utilizarea lor în limbajul Java.+Scopul acestui laborator este de a înțelege principiul **abstractizării**,​ prin prezentarea conceptelor de **interfață** și de **clasă abstractă** și utilizarea lor în limbajul Java.
  
 Conceptele de metode și clase abstracte și de interfețe sunt prezente și în alte limbaje OOP, fiecare cu particularitățile lor de sintaxă. Este important ca în urma acestui laborator să înțelegeți ce reprezintă și situațiile în care să le folosiți. Conceptele de metode și clase abstracte și de interfețe sunt prezente și în alte limbaje OOP, fiecare cu particularitățile lor de sintaxă. Este important ca în urma acestui laborator să înțelegeți ce reprezintă și situațiile în care să le folosiți.
Line 18: Line 20:
  
 Clasa ''​Instrument''​ nu este instanţiată niciodată pentru că scopul său este de a stabili o interfaţă comună pentru toate clasele derivate. În același sens, metodele clasei de bază nu vor fi apelate niciodată. Apelarea lor este ceva greșit din punct de vedere conceptual. Clasa ''​Instrument''​ nu este instanţiată niciodată pentru că scopul său este de a stabili o interfaţă comună pentru toate clasele derivate. În același sens, metodele clasei de bază nu vor fi apelate niciodată. Apelarea lor este ceva greșit din punct de vedere conceptual.
 +
 +==== Abstractizare ====
 +
 +Abstractizarea este unul dintre cele 4 principii POO de bază (Abstractizare,​ Încapsulare,​ Moștenire, Polimorfism). Abstractizarea nu permite ca anumite caracteristici să fie vizibile în exterior. Acest lucru se referă la construirea unei interfețe comune, a unui șablon general pe care se bazează o anumită categorie de obiecte, fără a descrie explicit caracteristicile fiecaruia. Obiectele cunosc interfața comună pe care o au dar nu și cum este ea interpretată de fiecare obiect in parte. Acest lucru este realizat prin utilizarea claselor abstracte și a interfețelor.
  
 ==== Clase abstracte vs Interfețe ==== ==== Clase abstracte vs Interfețe ====
  
 Folosim o **clasă abstractă** atunci când vrem: Folosim o **clasă abstractă** atunci când vrem:
-  * sa implementăm doar unele din metodele din clasă+  * să implementăm doar unele dintre ​metodele din clasă
   * ca respectiva clasă să nu poată fi instanțiată   * ca respectiva clasă să nu poată fi instanțiată
  
Line 28: Line 34:
   * să avem doar o descriere a structurii, fără implementări   * să avem doar o descriere a structurii, fără implementări
   * ca interfața în cauză să fie folosită împreună cu alte interfețe în contextul moștenirii   * ca interfața în cauză să fie folosită împreună cu alte interfețe în contextul moștenirii
 +
 == Clase abstracte == == Clase abstracte ==
  
Line 41: Line 48:
 Pentru a exprima faptul că o metodă este abstractă (adică se declară doar interfaţa ei, nu și implementarea),​ Java folosește cuvântul cheie ''​abstract'':​ Pentru a exprima faptul că o metodă este abstractă (adică se declară doar interfaţa ei, nu și implementarea),​ Java folosește cuvântul cheie ''​abstract'':​
 <code java>​abstract void f();</​code>​ <code java>​abstract void f();</​code>​
-O clasă care conţine **metode abstracte** este numită **clasă abstractă**. Dacă o clasă are una sau mai multe metode abstracte atunci ea trebuie să conţină în definiţie cuvântul ''​abstract''​.+O clasă care conţine **metode abstracte** este numită **clasă abstractă**. Dacă o clasă are una sau mai multe metode abstracteatunci ea trebuie să conţină în definiţie cuvântul ''​abstract''​.
  
 Exemplu: Exemplu:
Line 200: Line 207:
  
 </​code>​ </​code>​
-Se observă că ''​Hero''​ combină clasa ''​ActionCharacter''​ cu interfeţele ''​CanSwim'' ​etc. Acest lucru se realizează specificând prima data clasa concretă (sau abstractă) (extends) și abia apoi ''​implements''​. +Se observă că ''​Hero''​ combină clasa ''​ActionCharacter''​ cu interfeţele ''​CanSwim''​, ''​CanFight'',​ ''​CanFly''​. Acest lucru se realizează specificând prima data clasa concretă (sau abstractă) (extends) și abia apoi ''​implements''​. 
-Metodele clasei ''​Adventure''​ au drept parametri interfeţele ''​CanSwin'' ​etc. si clasa ''​ActionCharacter''​. La fiecare apel de metodă din ''​Adventure''​ se face **upcast** de la obiectul ''​Hero''​ la clasa sau interfaţa dorită de metoda respectivă.+Metodele clasei ''​Adventure''​ au drept parametri interfeţele ''​CanSwin''​, ''​CanFight'',​ ''​CanFly'' ​si clasa ''​ActionCharacter''​. La fiecare apel de metodă din ''​Adventure''​ se face **upcast** de la obiectul ''​Hero''​ la clasa sau interfaţa dorită de metoda respectivă.
  
 ==== Coliziuni de nume la combinarea interfeţelor ==== ==== Coliziuni de nume la combinarea interfeţelor ====
Line 225: Line 232:
  
 ==== Exerciţii ====  ==== Exerciţii ==== 
-1. (**2p**) Implementaţi interfaţa ''​Task'' ​(din pachetul ''​first''​) ​în cele 3 moduri de mai jos. + 
-* Un task care să afișeze un mesaj la output. Mesajul este specificat în constructor. (''​OutTask.java''​) +**Contest LambdaChecker**:​ [[https://​beta.lambdachecker.io/​contest/​56/​problems?​page=1|Laborator5]] 
-* Un task care generează un număr aleator și afișează un mesaj cu numărul generat la output. Generarea se face în constructor. (''​RandomOutTask.java''​) + 
-* Un task care incrementează un contor global și afișează valoarea contorului după fiecare incrementare (''​CounterOutTask.java''​).+1. (**2 puncte**) Implementaţi interfaţa ''​Task''​ în cele 3 moduri de mai jos. 
 +  * Un task care să afișeze un mesaj la output. Mesajul este specificat în constructor. (''​OutTask.java''​) 
 +  * Un task care generează un număr aleator ​de tip ''​int'' ​și afișează un mesaj cu numărul generat la output. Generarea se va realiza ​în constructor ​utilizându-se o instanța globală a unui obiect de tip ''​Random''​ care a fost inițializat cu seed-ul **12345** [[https://​docs.oracle.com/​javase/​8/​docs/​api/​java/​util/​Random.html#​Random-long-|Random]]. (''​RandomOutTask.java''​) 
 +  * Un task care incrementează un contor global și afișează valoarea contorului după fiecare incrementare (''​CounterOutTask.java''​).
  
 <​note>​**Notă**:​ Acesta este un exemplu simplu pentru [[http://​en.wikipedia.org/​wiki/​Command_pattern|Command Pattern]]</​note>​ <​note>​**Notă**:​ Acesta este un exemplu simplu pentru [[http://​en.wikipedia.org/​wiki/​Command_pattern|Command Pattern]]</​note>​
Line 234: Line 244:
 {{:​poo-ca-cd:​laboratoare:​clase-abstracte-interfete:​ex1.png?​600|}} {{:​poo-ca-cd:​laboratoare:​clase-abstracte-interfete:​ex1.png?​600|}}
  
-2. (**3p**) Interfaţa ''​Container'' ​(din pachetul ''​second''​) ​specifică interfaţa comună pentru colecţii de obiecte Task, în care se pot adăuga și din care se pot elimina elemente. Creaţi două tipuri de containere care implementează această clasă: +2. (**3 puncte**) Interfaţa ''​Container''​ specifică interfaţa comună pentru colecţii de obiecte Task, în care se pot adăuga și din care se pot elimina elemente. Creaţi două tipuri de containere care implementează această clasă: 
-  - (**1.5p**) ​''​Stack''​ - care implementează o strategie de tip [[https://​en.wikipedia.org/​wiki/​Stack_(abstract_data_type)|LIFO]] +  - ''​Stack''​ - care implementează o strategie de tip [[https://​en.wikipedia.org/​wiki/​Stack_(abstract_data_type)|LIFO]] 
-  - (**1.5p**) ​''​Queue''​ - care implementează o strategie de tip [[https://​en.wikipedia.org/​wiki/​Queue_(abstract_data_type)|FIFO]]+  - ''​Queue''​ - care implementează o strategie de tip [[https://​en.wikipedia.org/​wiki/​Queue_(abstract_data_type)|FIFO]]
  
-<note important>​**Evitaţi codul similar** în locuri diferite!</​note>​+**Bonus**: Incercați să evitaţi codul similar în locuri diferite!
  
-<note tip>​**Hint**:​ Puteţi reţine intern colecţia de obiecte, utilizând clasa [[http://​docs.oracle.com/​javase/​8/​docs/​api/​java/​util/​ArrayList.html|ArrayList]] din SDK-ul Java. Iată un exemplu de iniţializare pentru șiruri:+<note tip>​**Hint**:​ Puteţi reţine intern colecţia de obiecte, utilizând clasa [[http://​docs.oracle.com/​javase/​8/​docs/​api/​java/​util/​ArrayList.html|ArrayList]] din SDK-ul Java.
  <​code java>  <​code java>
-ArrayList<​String> list = new ArrayList<​String>();+ArrayList<​Task> list = new ArrayList<​Task>();
 </​code></​note>​ </​code></​note>​
  
 {{:​poo-ca-cd:​laboratoare:​clase-abstracte-interfete:​ex2.png?​600|}} {{:​poo-ca-cd:​laboratoare:​clase-abstracte-interfete:​ex2.png?​600|}}
  
-3. (**2p**) Implementaţinterfaţa ​''​IFactory'' ​(clasa ​''​ContainerFactory'', ​din pachetul ​''​third''​care conţine o metodă ce primește ​ca parametru o strategie (enum ''​Strategy''​) ​și care întoarce un container asociat acelei strategiiDin acest punct înainte, în programul vostru veţi crea containere folosind doar această clasă (nu puteţcrea direct obiecte de tip Stack sau Queue)+3. (**2 puncte**) Creaț4 interfețe: ​''​Minus''​''​Plus'', ​ ''​Mult'',​ ''​Div''​ care conțin câte o metodă ​aferentă numelui ​ce are ca argument un numar de tipul float. 
 + 
 +Spre exemplu interfata ​''​Minus'' ​va declara metoda: 
 +<code java> 
 +void minus(float value)
 +</​code>​ 
 +Scriețclasa ''​Operation'' ​care să implementeze toate aceste interfețePe lânga metodele interfețelor implementate aceasta va conține: 
 +  * un câmp ''​number''​ de tipul ''​float''​ asupra căruia se vor efectua operațiile implementate 
 +  * o metodata getter ''​getNumber''​ care va returna valoarea câmpului ''​value''​ 
 +  * un constructor care primește ca parametru valoarea inițială pentru campul ''​value''​ 
 + 
 +Pentru cazul în care metoda div este apelată cu valoare 0 operația ​nu va fi efectuată șse va afișa mesajul "​Division by 0 is not possible"​.
  
-<note important>​**Evitaţi** instanţierea clasei Factory implementate de voi la fiecare creare a unui container!</​note>​+4. (**3 puncte**) Implementaţi clasa ''​Song''​ și clasa abstracta ''​Album''​.
  
-<​note>​**Notă**: Acest mod de a crea obiecte de tip Container elimină problema ​care apare în momentul în care decidem să folosim o implementare diferită pentru un anumit ​tip de strategie ​și nu vrem să facem modificări și în restul programului. De asemenea o astfel de abordare este utilă când avem implementări care urmăresc scopuri diferite ​(putem avea un Factory ​care să creeze containere optimizate pentru viteză sau un Factory cu containere ce folosesc minimum de memorie). șablonul acesta de programare poartă denumirea de [[http://​en.wikipedia.org/​wiki/​Factory_method_pattern|Factory Method Pattern]].</​note>​+Song:  
 +  ​stochează atributele ''​name'':​ ''​String'',​ ''​id'':​ ''​int'',​ ''​composer'':​ ''​String''​ 
 +  ​implementează un constructor ​care va inițializa atributele specificate anterior 
 +  * implementează metodele de tip getter ​și setter pentru fiecare atribut 
 +  * suprascrie metoda ''​toString()'' ​care va returna ​un ''​String''​ forma "​Song{name=''​name'',​ id=''​id'',​ composer=''​composer''​}"​
  
-{{:​poo-ca-cd:​laboratoare:​clase-abstracte-interfete:​ex3.png?250|}}+Album: 
 +  * stochează o listă de cântece (puteți folosi ArrayList)  
 +  * declară metoda abstractă ''​void addSong(Song song)''​ 
 +  * implementează metodele ''​void removeSong(Song song)''​ 
 +  * suprascrie metoda ''​toString()''​ care va returna un ''​String''​ forma "Album{songs=[''​Song'',​ ''​Song'',​ ''​...''​]}
  
-4. (**3p**) Extindeţclasa ''​AbstractTaskRunner'' ​(din pachetul ​''​fourth''​) în 3 moduri: +După implementarea claselor ''​Song''​ și ''​Album'' ​creați clasele ​''​DangerousAlbum''​''​ThrillerAlbum''​ și ''​BadAlbum''​ care vor moșteni clasa ''​Album''​ și vor implementa metoda ''​addSong'' ​după următoarele reguli:  
-  * (**1p**) ​''​PrintTimeTaskRunner'' ​care afișează un mesaj după execuţia unui task în care se specifică ora la care s-a executat task-ul (vedeți clasa [[https://​docs.oracle.com/​javase/​8/​docs/​api/​java/​util/​Calendar.html|Calendar]]). +  * ''​DangerousAlbum'' ​conține doar melodii cu id-ul număr prim 
-  * (**1p**)  ​''​CounterTaskRunner''​ -  ​incrementează un contor local care ţine minte câte task-uri s-au executat. +  * ''​ThrillerAlbum''​ conține melodii scrise doar de ''​Michael Jackson''​ și au id-ul număr par  
-  * (**1p**) ​''​RedoBackTaskRunner'' ​- salvează fiecare task executat într-un container în ordinea inversă a execuţiei ​și are o metodă prin care se permite reexecutarea task-urilor. +  * ''​BadAlbum'' ​conține doar melodii care au nume de 3 litere ​și id număr palindrom
-{{:​poo-ca-cd:​laboratoare:​clase-abstracte-interfete:​ex4.png?​650|}} +
-==== Resurse ====+
  
-  * {{:​poo-ca-cd:​laboratoare:​clase-abstracte-interfete:​lab4_schelet.zip|Schelet}} +În cazul în care criteriul de adaugare specific unui album nu este respectat melodia nu va fi adaugată în acesta
-  * {{:​poo-ca-cd:​laboratoare:​clase-abstracte-interfete:​|Soluție}} +
-  * <​html><​a class="​media mediafile mf_pdf"​ href="/​poo/​laboratoare/​clase-abstracte-interfete?​do=export_pdf">​PDF laborator</​a></​html>​+
  
poo-ca-cd/laboratoare/clase-abstracte-interfete.1601732092.txt.gz · Last modified: 2020/10/03 16:34 by mconstantin1412
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