User Tools

Site Tools


Problem constructing authldap
laboratoare:old-exercises

This is an old revision of the document!


Exerciții

Această pagină cuprinde exerciții care au fost taskuri de laborator și acum înlocuite cu altele.

Puteți folosi aceste exerciții pentru a vă exersa noțiunile învățate la curs și la laboratoare.

Elemente de sintaxă, primitive, stringuri

  1. Numere complexe
    1. Creați un proiect nou cu numele ComplexNumber.
    2. Creați clasa ComplexNumber.java. Aceasta va avea două campuri: re si im, ambele de tip float.
  2. Operații
    1. Creați clasa Operations.java. Această clasă va implementa operațiile de adunare și înmulțire pentru numere complexe. Definiți în clasă Operations câte o metodă pentru fiecare operație;
    2. Testați metodele implementate.
  3. Biblioteca
    1. Creați un proiect nou cu numele Bookstore.
    2. Creați clasa Book.java cu următoarele atribute: title, author, publisher, pageCount.
    3. Creați clasa BookstoreTest.java, pentru a testa viitoarele funcționalități ale bibliotecii. Completați această clasă, așa cum considerați necesar. Apoi, creați un obiect de tip carte și setați atributele introducând date de la tastatură. Pentru această folosiți clasa Scanner:
    •      Scanner s = new Scanner(System.in);
           String title = s.nextLine();
       
  4. Verificați ca numărul de pagini introdus să fie diferit de zero. Puteți consulta documentația claselor String și Integer.
  5. Verificări cărți
    1. Creați o clasă nouă, BookstoreCheck, ce va conține două metode, cu câte 2 parametri de tipul Book.
      • Prima metodă va verifica dacă o carte este în dublu exemplar, caz în care va întoarce adevărat.
      • A doua metodă va verifica care carte este mai groasă decât altă, și va întoarce cartea mai groasă.
    2. Testați aceste doua metode.
  6. Formatare afișare
    • Puteți consulta documentația clasei String
    • Afișați informația despre o carte în felul următor:
BOOK_TITLE: [insert_book_title]
BOOK_AUTHOR: [insert_book_author]
BOOK_PUBLISHER: [insert_book_publisher]

Cu următoarele precizări:

  • Titlul cărții va fi scris în întregime cu majuscule
  • Numele editurii va fi scris în întregime cu minuscule
  • Numele autorului rămânând neschimbat

Specificatori de acces

  1. Implementaţi o clasă MyArrayList, care va reprezenta un vector de numere reale, cu posibilitatea redimensionării automate. Ea va fi definită în pachetul arrays. Clasa va conţine următoarele metode:
    • un constructor fără parametri, care creează intern un vector cu 10 elemente
    • un constructor cu un parametru de tipul întreg, care creează un vector de dimensiune egală cu parametrul primit
    • o metodă numită add(float value), care adaugă valoarea value la finalul vectorului. Dacă se depăşeşte capacitatea vectorului, acesta se va redimensiona la o capacitate dublă
      • Atenţie! Există o diferenţă între capacitatea vectorului (dimensiunea cu care a fost iniţializat) şi numărul de elemente memorate efectiv în el (care este cel mult capacitatea).
    • o metodă numită contains(float value) care returnează true dacă value există în cadrul vectorului
    • o metodă numită remove(int index) care elimină valoarea aflată în vector la poziţia specificată de index (numerotarea incepând de la 0); se va da un mesaj dacă indexul este invalid
    • o metodă numită get(int index) care va returna elementul aflat în poziţia index
    • o metodă numită size() care returnează numarul de elemente din vector
    • o metodă declarată public String toString() care va returna o reprezentare a tuturor valorilor vectorului ca un şir de caractere
  2. Scrieţi o clasă de test separată pentru clasa MyArrayList, populând lista cu 3 elemente şi verificând că valorile întoarse de metoda get corespund, într-adevăr, poziţiilor aferente din vectorul intern clasei. Ce condiţii trebuie îndeplinite pentru atingerea scopului propus?
  3. Scrieţi un scenariu de utilizare a clasei MyArrayList, astfel:
    • iniţializând-o cu o capacitate de 5 de elemente iar apoi inserând 10 elemente aleatoare utilizând doar metoda add
    • cautând 5 valori aleatoare în vector
    • eliminând 5 valori aleatoare din vector
  4. De multe ori este bine ca programarea unor aplicaţii mari să se faca modular, un modul fiind gestionat de o anumită clasă. De asemenea, în cadrul acestor aplicaţii, puteţi avea situaţii în care o metodă are nevoie să utilizeze mai multe module, deci să primească referinţele mai multor clase, fapt ce poate deveni dificil de gestionat. De aceea, aceste clase se pot implementa limitând accesul la o singură instanţă statică, ceea ce permite accesarea acesteia doar pe baza clasei, fară a mai fi necesară trimiterea ei ca parametru in metode. Aşa descoperim un prim design pattern orientat-obiect; el se numeşte Singleton şi puteţi afla câteva despre el aici. Ne propunem să implementăm o variantă simplă. Creaţi clasa Singleton, care să
    • aibă intern o singură instanţă statică
    • aibă un constructor privat (de ce e nevoie?)
    • expună o metodă publică de acces la instanţă (un getter)

Agregare și moștenire

  1. Întrucât în ierarhia de clase Java, clasa Object se află în rădăcina arborelui de moștenire pentru orice clasă, orice clasă va avea acces la o serie de facilități oferite de Object. Una dintre ele este metoda toString(), al cărei scop este de a oferi o reprezentare a unei instanțe de clasă sub forma unui șir de caractere.
    • Definiți clasa Form cu un membru color de tip String, o metoda getArea() care pentru început va intoarce 0 și o metodă toString() care va returna acestă culoare.
    • Clasa va avea, de asemenea:
      • un constructor fără parametri
      • un constructor ce va inițializa culoarea.
    • Din ea derivați clasele Triangle și Circle:
      • Clasa Triangle va avea 2 membri height si base de tip float.
      • Clasa Circle va avea membrul radius de tip float.
      • Clasele vor avea:
        • constructori fără parametri
        • constructori care permit inițializarea membrilor. Identificați o modalitate de reutilizare a codului existent.
    • Instanțiati clasele Triangle și Circle, și apelați metoda toString() pentru fiecare instanță.
    • suprascrieti metoda getArea() pentru a intoarce aria specifica figuri geometrice.
  2. Adăugați metode toString() în cele două clase derivate, care să returneze tipul obiectului, culoarea si aria. De exemplu:
    • pentru clasa Triangle, se va afișa: “Triunghi: rosu 10”
    • pentru clasa Circle, se va afișa: “Cerc: verde 12.56”
    • Modificați implementarea toString() din clasele derivate astfel încât aceasta să utilizeze implementarea metodei toString() din clasa de bază.
  3. Adăugați o metodă equals în clasa Triangle. Justificați criteriul de echivalentă ales.
    • Hint: vedeți metodele clasei Object, moștenită de toate clasele - Object are metoda equals, a cărei implementare verifică echivalența obiectelor comparând referințele.
  4. Upcasting.
    • Creați un vector de obiecte Form și populați-l cu obiecte de tip Triangle și Circle (upcasting).
    • Parcurgeți acest vector și apelați metoda toString() pentru elementele sale. Ce observați?
  5. Downcasting.
    • Adăugați clasei Triangle metoda printTriangleDimensions și clasei Circle metoda printCircleDimensions. Implementarea metodelor constă în afișarea bazei si inaltimii respectiv razei.
    • Parcurgeți vectorul de la exercițiul anterior și, folosind downcasting la clasa corespunzătoare, apelați metodele specifice fiecărei clase (printTriangleDimensions pentru Triangle și printCircleDimensions pentru Circle). Pentru a stabili tipul obiectului curent folosiți operatorul instanceof.
    • Modificați programul anterior astfel încât downcast-ul să se facă mereu la clasa Triangle. Ce observați?
    • Modificați programul anterior astfel încât să nu mai aveți nevoie de instanceof deloc.
  6. Implementați două clase QueueAggregation și QueueInheritance pe baza clasei Array furnizate de noi, utilizând, pe rând, ambele abordări: moștenire și agregare. Precizări:
    • Coada va conține elemente de tip int.
    • Clasele QueueAggregation și QueueInheritance trebuie să ofere metodele enqueue și dequeue, specifice acestei structuri de date.
    • Clasa Array reprezintă un wrapper pentru lucrul cu vectori. Metoda get(pos) întoarce valoarea din vector de la poziția pos, în timp ce metoda set(pos, val) atribuie poziției pos din vector valoarea val. Noutatea constă în verificarea poziției furnizate. În cazul în care aceasta nu se încadrează în intervalul valid de indici, ambele metode întorc constanta ERROR definită în clasa.
    • Metoda main definită în clasa Array conține exemple de utilizare a acestei clase. Experimentați!
    • Metoda enqueue va oferi posibilitatea introducerii unui număr întreg în capătul cozii (dacă aceasta nu este deja plină), în timp ce metoda dequeue va înlătura elementul din vârful cozii și îl va întoarce (dacă coada nu este goală). În caz de insucces (coada plină la enqueue, respectiv goală la dequeue), ambele metode vor întoarce constanta ERROR.
    • Ce problemă poate apărea din cauza constantei ERROR? (Hint: Dacă în coadă am un element egal cu valoarea constantei ERROR?) Gândiți-vă la o rezolvare.
    • Ce puteți spune despre vizibilitatea metodelor get și set, în clasele QueueAggregation și QueueInheritance, în varianta ce utilizează moștenire? Ce problemă indică răspunsul? Furnizați o soluție la această problemă.

Clase abstracte și interfețe

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)
  • 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).Notă: Acesta este un exemplu simplu pentru Command Pattern

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ă: 1. (1.5p) Stack - care implementează o strategie de tip LIFO

2. (1.5p) Queue - care implementează o strategie de tip FIFO

Evitaţi codul similar în locuri diferite!

Hint: Puteţi reţine intern colecţia de obiecte, utilizând clasa ArrayList din SDK-ul Java. Iată un exemplu de iniţializare pentru șiruri:

ArrayList<String> list = new ArrayList<String>();

3. (2p) Implementaţi 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 strategii. Din acest punct înainte, în programul vostru veţi crea containere folosind doar această clasă (nu puteţi crea direct obiecte de tip Stack sau Queue). Evitaţi instanţierea clasei Factory implementate de voi la fiecare creare a unui container! 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 Factory Method Pattern.

4. (3p) Extindeţi clasa AbstractTaskRunner (din pachetul fourth) în 3 moduri:

  • (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 Calendar).
  • (1p) CounterTaskRunner - incrementează un contor local care ţine minte câte task-uri s-au executat.
  • (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.

Schelet: lab4_schelet_2018.zip

laboratoare/old-exercises.1571507689.txt.gz · Last modified: 2019/10/19 20:54 by Adriana Draghici