This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
laboratoare:genericitate [2018/10/19 19:24] Adriana Draghici [Introducere] |
laboratoare:genericitate [2019/11/24 19:44] (current) Florin Mihalache [Exerciții] |
||
---|---|---|---|
Line 1: | Line 1: | ||
= Genericitate = | = Genericitate = | ||
+ | |||
+ | == Obiective == | ||
+ | |||
+ | |||
+ | Scopul acestui laborator este prezentarea conceptului de genericitate și modalitățile de creare și folosire a claselor, metodelor și interfețelor generice în Java. | ||
+ | |||
+ | Aspectele urmărite sunt: | ||
+ | * prezentarea structurilor generice simple | ||
+ | * conceptele de wildcard și bounded wildcards | ||
+ | * utilitatea genericității în design-ul unui sistem | ||
+ | |||
== Introducere == | == Introducere == | ||
Line 35: | Line 46: | ||
void add(E x); | void add(E x); | ||
Iterator<E> iterator(); | Iterator<E> iterator(); | ||
- | ... | ||
} | } | ||
Line 45: | Line 55: | ||
</code> | </code> | ||
- | Sintaxa ''<E>'' este folosită pentru a defini tipuri formale în cadrul interfețelor. Aceste tipuri pot fi folosite în mod asemănător cu tipurile uzuale, cu anumite restricții totuși. În momentul în care invocăm o structură generică ele vor fi înlocuite cu tipurile efective utilizate în invocare. Concret, fie un apel de forma: | + | Sintaxa ''<E>'' (poate fi folosită orice literă) este folosită pentru a defini tipuri formale în cadrul interfețelor. Aceste tipuri pot fi folosite în mod asemănător cu tipurile uzuale, cu anumite restricții totuși. În momentul în care invocăm o structură generică ele vor fi înlocuite cu tipurile efective utilizate în invocare. Concret, fie un apel de forma: |
<code java> | <code java> | ||
Line 53: | Line 63: | ||
În această situație, tipul formal ''E'' a fost înlocuit (la compilare) cu tipul efectiv ''Integer''. | În această situație, tipul formal ''E'' a fost înlocuit (la compilare) cu tipul efectiv ''Integer''. | ||
- | |||
- | <note> | ||
- | O analogie (simplistă) referitoare la acest mecanism de lucru cu tipurile se poate face cu mecanismul funcțiilor: acestea se definesc utilizând parametri //formali//, urmând ca în momentul unui apel acești parametri să fie înlocuiți cu parametri //actuali//. | ||
- | </note> | ||
== Genericitatea în subtipuri == | == Genericitatea în subtipuri == | ||
Line 167: | Line 173: | ||
<note> | <note> | ||
- | Trebuie reținut faptul că **în continuare nu putem introduce valori** într-o colecție ce folosește //bounded wildcards// și este dată ca parametru unei funcții. | + | Utilizarea bounded wildcards se manifestă în următoarele 2 situații : |
+ | * lower bounded wildcards se folosesc atunci când vrem să **modificăm** o colecție generică | ||
+ | * upper bounded wildcards se folosesc atunci când vrem să **parcurgem fără să modificăm** o colecție generică | ||
</note> | </note> | ||
Line 259: | Line 267: | ||
* (**1p**) Implementaţi metoda **get**. | * (**1p**) Implementaţi metoda **get**. | ||
* (**1p**) Testaţi implementarea voastră folosind o clasă definită de voi, care suprascrie metoda **hashCode** din ''Object''. | * (**1p**) Testaţi implementarea voastră folosind o clasă definită de voi, care suprascrie metoda **hashCode** din ''Object''. | ||
- | * (**Bonus 2p**) Implementați tabela de dispersie ca //iterabilă//, compatibilă cu syntactic-sugar-ul **for-each** | ||
- | * Trebuie să implementați interfața ''Iterable''. Atenție, și ea este generică. | ||
- | * Creați-vă //iteratorul//, parametrizat, ca o clasă internă care să rețină datele necesare. | ||
- | * Nu este necesar să implementați metoda ''remove'' din ''Iterator''. | ||
- | * Afișați-vă rezultatele folosind **for-each** pe tabela de dispersie. | ||
- (**4p**) Să considerăm interfața ''Sumabil'', ce conține metoda ''void addValue(Sumabil value)''. Această metodă adună la valoarea curentă (stocată în instanța ce apelează metoda) o altă valoare, aflată într-o instanță cu același tip. Pornind de la această interfață, va trebui să: | - (**4p**) Să considerăm interfața ''Sumabil'', ce conține metoda ''void addValue(Sumabil value)''. Această metodă adună la valoarea curentă (stocată în instanța ce apelează metoda) o altă valoare, aflată într-o instanță cu același tip. Pornind de la această interfață, va trebui să: | ||
* Definiți clasele ''MyVector3'' și ''MyMatrix'' (ce reprezintă un vector cu 3 coordonate și o matrice de dimensiune 4 x 4), ce implementează Sumabil | * Definiți clasele ''MyVector3'' și ''MyMatrix'' (ce reprezintă un vector cu 3 coordonate și o matrice de dimensiune 4 x 4), ce implementează Sumabil |