User Tools

Site Tools


Problem constructing authldap
laboratoare:constructori-referinte
Differences

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

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
laboratoare:constructori-referinte [2018/10/08 12:10]
Andrei Vasiliu
laboratoare:constructori-referinte [2020/01/14 14:00] (current)
Adriana Draghici bold
Line 7: Line 7:
 Aspectele urmărite sunt: Aspectele urmărite sunt:
 * tipurile de contructori și crearea de instanţe ale claselor folosind acești constructori * tipurile de contructori și crearea de instanţe ale claselor folosind acești constructori
-* utilizarea ​cuvintelor-cheie **this**, **final** și **static** +* utilizarea ​cuvântului-cheie **this**
-* însușirea noțiunii de obiect **imutabil**+
  
 == Constructori == == Constructori ==
Line 153: Line 152:
         // ERROR: the implicit constructor is hidden by the constructor with parameters         // ERROR: the implicit constructor is hidden by the constructor with parameters
         Student s = new Student();         Student s = new Student();
 +    }
 +}
 +</​code>​
 +
 +În Java, există conceptul de **copy constructor**,​ acesta reprezintând un constructor care ia ca parametru un obiect de același tip cu clasa în care se află constructorul respectiv. Cu ajutorul acestui constructor,​ putem să copiem obiecte, prin copierea membru cu membru în constructor.
 +
 +<code java5>
 +public class Student {
 +    private String name;
 +    private int averageGrade;​
 +
 +    public Student(String name, int averageGrade) {
 +        this.name = name;
 +        this.averageGrade = averageGrade;​
 +    }
 +
 +    // copy constructor
 +    public Student(Student student) {
 +        // name este camp privat, noi il putem accesa direct (student.name) ​
 +        // deoarece ne aflam in interiorul clasei
 +        this.name = student.name;​
 +        this.averageGrade = student.averageGrade;​
     }     }
 } }
Line 276: Line 297:
 </​code>​ </​code>​
  
-== Cuvântul-cheie "​final"​. Obiecte immutable ​==+== Metoda toString() ​== 
 +Cu ajutorul metodei toString(), care este deja implementată by default pentru fiecare clasă în Java, aceasta întorcând un string, putem obține o reprezentare a unui obiect ca string. În cazurile claselor implementate de utilizator, este de recomandat să implementăm (mai precis, să suprascriem - detalii despre suprascrierea metodelor în următoarele laboratoare) metoda toString() în clasele definite de către utilizator.
  
-Variabilele declarate cu atributul ''​final''​ pot fi inițializate **o singură dată**. Observăm că astfel unei variabile ​de tip referință care are atributul ''​final''​ îi poate fi asignată o singură valoare ​(variabila poate puncta către un singur obiect). O încercare nouă de asignare a unei astfel de variabile va avea ca efect generarea unei erori la compilare.+Un exemplu ​de implementare a metodei toString()
 +<code java5 Student.java> 
 +public class Student { 
 +    private String name; 
 +    private int averageGrade;​
  
-Totușiobiectul către care punctează o astfel de variabilă poate fi modificat intern, prin apeluri de metode sau acces la câmpuri.+    public Student(String nameint averageGrade) { 
 +        this.name = name; 
 +        this.averageGrade = averageGrade;​ 
 +    }
  
-Exemplu:  +    @Override 
- +    public ​String toString() { 
-<code java5> +        ​return "Nume student: " + name + "​\nMedia studentului:​ " + averageGrade;
-class Student { +
- +
-    private final Group group; ​                     // a student can change the group he was assigned in +
-    private static final int UNIVERSITY_CODE = 15; // declaration of an int constant +
- +
-    public ​Student(Group group) { +
-        ​// reference initialization;​ any other attempt to initialize it will be an error +
-        this.group = group;+
     }     }
 } }
 </​code>​ </​code>​
  
-Dacă toate atributele unui obiect admit o unică inițializare,​ spunem că obiectul respectiv este ''​immutable'',​ în sensul că //nu putem schimba obiectul in sine (informatia pe care o stocheaza, de exemplu), ci doar referinta catre un alt obiect.//. Exemple de astfel de obiecte sunt instanțele claselor ''​String''​ și ''​Integer''​. Odată create, prelucrările asupra lor (ex.: ''​toUpperCase()''​) se fac prin **instantierea de noi obiecte** și nu prin alterarea obiectelor înseși. +Folosirea metodei toString():
- +
-Exemplu: +
 <code java5> <code java5>
-String s1 = "abc";+Student st1 new Student("Decebal Popescu", 5); 
 +/* 
 +nu este neaparat sa scriem st1.toString() la apelul metodei println 
 +println apeleaza in mod automat metoda toString in acest caz 
 +*/ 
 +System.out.println(st1);​ 
 +/* 
 +se va afisa urmatorul string
  
-String s2 = s1.toUpperCase(); ​    // s1 does not change; the method returns a reference to a new object which can be accessed using s2 variable +Nume student: Decebal Popescu 
-s1 = s1.toUpperCase();​ /s1 is now a reference to a new object+Media studentului:​ 5 
 +*/
 </​code>​ </​code>​
-<note tip> 
-Observăm că în acest exemplu am folosit un String literal. Literalii sunt păstrați într-un ''​String pool''​ pentru a limita memoria utilizată. Asta înseamnă că dacă mai declarăm un alt literal "​abc",​ nu se va mai aloca memorie pentru încă un String, ci vom primi o referință către s-ul inițial. În cazul în care folosim constructorul pentru String se aloca memorie pentru obiectul respectiv și primim o referință nouă. 
-Pentru a evidentia concret cum functioneaza acest ''​String pool'',​ sa luam urmatorul exemplu: 
-</​note>​ 
-<code java5> 
-String s1 = "​a"​ + "​bc";​ 
-String s2 = "​ab"​ + "​c";​ 
-</​code>​ 
-În momentul în care compilatorul va încerca să aloce memorie pentru cele 2 obiecte, va observa că ele conțin, de fapt, aceeași informație. Prin urmare, va instanția un singur obiect, către care vor pointa ambele variabile, s1 și s2. Observați că această optimizare (de a reduce memoria) e posibilă datorită faptului că obiectele de tip String sunt **immutable**. 
  
-O intrebare legitimă este, așadar, cum putem compara două String-uri (ținând cont de faptul că avem referințele către ele, cum am arătat mai sus). Să urmărim codul de mai jos:+==Exerciții==
  
-<code java5> +**Task 1** - 3 puncte
-String a = "​abc";​ +
-String b = "​abc";​ +
-System.out.println(a == b);  // True+
  
-String c = new String("​abc"​); +Să se creeze o clasă numită //​Complex//,​ care are doi membri de tip int (real și imaginary), care vor fi de tip private. Realizați următoarele subpuncte: 
-String d = new String("​abc"​); +    * să se creeze trei constructori:​ primul primește doi parametri de tip int (primul desemnează partea reală a unui număr complex, al doilea partea imaginară),  al doilea nu primește niciun parametru și apelează primul constructor cu valorile 0 și 0, iar al treilea reprezinta un copy constructor,​ care primește ca parametru un obiect de tip Complex, care este copiat în obiectul //this// 
-System.out.println(c == d);  ​// False +    * să se scrie metode de tip getter și setter ​(remember primul laborator - proprietăți), prin care putem accesa membrii privați ai clasei 
-</code>+    * să se scrie o metodă de tip void numită ''​addWithComplex'',​ care primește ca parametru un obiect de tip Complex, prin care se adună numărul complex dat ca parametru la numărul care apelează funcția (adică la //this//) 
 +    * să se scrie o metodă de tip void numita ''​showNumber'',​ prin care se afișează numărul complex
  
-<note important>​ +**Task 2** - 2 puncte
-Operatorul <​nowiki>"​=="</​nowiki>​ compară //​referințele//​. Dacă am fi vrut să comparăm șirurile în sine am fi folosit metoda ''​equals''​. Același lucru este valabil și pentru oricare alt tip referință:​ operatorul <​nowiki>"​=="</​nowiki>​ testează egalitatea //​referințelor//​ (i.e. dacă cei doi operanzi sunt de fapt același obiect).+
  
 +Aveți in scheletul laboratorului un cod, care conține două greșeli legate de referințe. Rolul vostru este să corectați aceste greșeli încât codul să aibă comportamentul dorit (există comentarii în cod despre modul cum ar trebui să se comporte).
  
-Dacă vrem să testăm "​egalitatea"​ a două obiecte, se apelează metoda: ''​public boolean equals(Object obj)''​. 
  
-Reţineţi semnătura acestei metode! +** Task 3** - 3 puncte
-</​note>​+
  
-== Cuvântul-cheie "​static"​ ==+Să se implementeze o clasă// Point// care să conțină:​ 
 +* un constructor care să primească cele două numere reale (de tip float) ce reprezintă coordonatele. 
 +* o metodă ''​changeCoords''​ ce primește două numere reale și modifică cele două coordonate ale punctului. 
 +* o funcție de afișare a unui punct astfel: (x, y).
  
-După cum am putut observa până acum, de fiecare dată când cream o instanță a unei clasevalorile câmpurilor din cadrul ​instanței sunt unice pentru aceasta ​și pot fi utilizate fără pericolul ca instaţierile următoare să le modifice în mod implicit.+Să se implementeze o clasă //Polygon// cu următoarele:​ 
 +* un constructor care preia ca parametru un singur număr n (reprezentând numărul ​de colțuri al poligonului) și alocă spațiu pentru puncte (un punct reprezentând ​o instanță a clasei Point). 
 +* un constructor care preia ca parametru un vectorcu 2n numere reale reprezentând colțurile. Acest constructor apelează constructorul de la punctul de mai sus și completează vectorul de puncte cu cele n instanțe ale clasei Point obținute din parametrii primiți. 
 +La final, afișcoordonatele poligonului utilizând metodă de afișare a clasei Point.
  
-Să exemplificăm aceasta:  +** Task 4** - 2 puncte
-  +
-<code java5> +
-Student instance1 = new Student("​Alice",​ 7); +
-Student instance2 = new Student("​Bob",​ 6); +
-</​code>​+
  
-În urma acestor apeluri, ''​instance1''​ și ''​instance2''​ vor funcționa ca entități independente una de cealaltă, astfel că modificarea câmpului ''​nume''​ din ''​instance1''​ nu va avea nici un efect implicit și automat ​în ''​instance2''​. Există însă posibilitatea ca uneori, anumite câmpuri din cadrul unei clase să aibă valori independente de instanțele acelei clase (cum este cazul câmpului ''​UNIVERSITY_CODE''​), astfel că acestea nu trebuie memorate separat pentru fiecare instanță.+În scheletul de cod aveți definită clasa //Book//, în care trebuie ​să implementați metoda [[https://​docs.oracle.com/​en/​java/​javase/​12/​docs/​api/​java.base/​java/​lang/​Object.html#​toString()|toString()]]și o clasă //Main//, în care se testează metoda toString() din Book. 
 +== Resurse ==
  
-Aceste câmpuri se declară cu atributul ​**static** și au o locație unică în memorie, care nu depinde de obiectele create din clasa respectivă.  +* {{:laboratoare:constructori-referinte:lab2-2019-schelet.zip|Schelet}
- +* {{:laboratoare:constructori-referinte:lab2-2019-sol.zip|Solutie}}
-Pentru a accesa un câmp static al unei clase (presupunând că acesta nu are specificatorul ''​private''​),​ se face referire la clasa din care provine, nu la vreo instanță. Același mecanism este disponibil și în cazul metodelor, așa cum putem vedea în continuare:  +
- +
-<code java5> +
-class ClassWithStatics ​{ +
- +
-    static String className = "Class With Static Members";​ +
-    private static boolean hasStaticFields = true; +
- +
-    public static boolean getStaticFields() ​{ +
-         ​return hasStaticFields;​ +
-    } +
-+
- +
-class Test { +
- +
-    public static void main(String[] args) { +
-        System.out.println(ClassWithStatics.className);​ +
-        System.out.println(ClassWithStatics.getStaticFields());​ +
-    } +
-}   +
-</​code>​ +
-== Exerciții == +
- +
-<note tip> +
- +
-Exercițiile se rezolvă în ordine. +
- +
-</​note>​ +
- +
-  - (**1p**) Să se implementeze o clasă ''​Point''​ care să conțină +
-    * un constructor care să primească cele două numere reale (de tip ''​float''​) ce reprezintă coordonatele.  +
-    * o metodă ''​changeCoords''​ ce primește două numere reale și modifică cele două coordonate ale punctului.  +
-    * o funcție de afișare a unui punct astfel''​(x,​ y)''​. +
-  ​(**2p**) Să se implementeze o clasă ''​Polygon''​ cu următoarele +
-    * un constructor care preia ca parametru un singur număr //n// (reprezentând numărul de colțuri al poligonului) și alocă spațiu pentru puncte (un punct reprezentând o instanță a clasei ''​Point''​).  +
-    * un constructor care preia ca parametru un vector, cu //2n// numere reale reprezentând colțurile. Acest constructor apelează constructorul de la punctul de mai sus și completează vectorul de puncte cu cele //n// instanțe ale clasei ''​Point''​ obținute din parametrii primiți.  +
-      * La final, afișați coordonatele poligonului utilizând metodă de afișare a clasei ''​Point''​.  +
-  ​(**1p**) Testați diferența de viteză introdusă de crearea de noi obiecteMăsurați diferența între folosirea ''​new Integer(2+3)''​ și ''​2+3'',​ după modelul de mai jos: +
-    * <code java>  +
-private long run() {  +
-    long start = System.nanoTime();​  +
-    f(); // function which run time we want to measure  +
-    return System.nanoTime() - start;  +
-}  +
-</​code>​  +
-  - (**1p**) Testați diferența de memorie utilizată între a folosi String literal și String obținut prin constructor. Construiți un vector de String. Umpleți acest vector în primă fază cu literal-ul ''"​abc"''​ și măsurați memoria utilizată. Apoi, umpleți vectorul cu ''​new String("​abc"​)''​ și măsurați memoria utilizată. Măsurarea memoriei utilizate se poate face folosind următoarea metodă: +
-    * <code java>  +
-public void showUsedMemory() ​ +
-    long usedMem = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();​  +
-    System.out.println(usedMem);​  +
-}  +
-</​code>​  +
-  - (**2p**) Să se implementeze o clasă ''​RandomStringGenerator''​ ce generează un String de o anumită lungime fixată, conținând caractere alese aleator dintr-un alfabet. Această clasă o să conțină următoarele +
-    * un constructor care primește lungimea șirului și alfabetul sub formă de String. Exemplu de utilizare: +
-      * <code java>  +
-myGenerator = new RandomStringGenerator(5,​ "​abcdef"​);​  +
-</​code>​  +
-    * o metodă ''​next()''​ care va returna un nou String random folosind lungimea și alfabetul primite de constructor.  +
-      * Pentru a construi String-ul, este utilă reprezentarea sub formă de șir de caractere ''​char[]''​ (char array). Pentru a construi un String pornind de la un char array procedăm ca în exemplul următor: +
-      * <code java>  +
-char[] a = {'​a','​b','​c'​};​  +
-String s = new String(a);  +
-</​code>​  +
-      * Conversia unui String la char array se face apelând metoda ''​toCharArray()''​ a String-ului de convertit.  +
-    * Pentru a genera valori aleatoare din domeniul [0, N 1], utilizați:​ +
-      * <code java>  +
-import java.util.Random;​  +
-Random generator = new Random();  +
-int value = generator.nextInt(N);​  +
-</​code>​  +
-  - (**3p**) Să se implementeze o clasă ''​PasswordMaker''​ ce generează, folosind ''​RandomStringGenerator'',​ o parolă pornind de la datele unei persoane. Această clasă o să conțină următoarele:​  +
-    * o constantă MAGIC_NUMBER având orice valoare doriți  +
-    * un String constant MAGIC_STRING,​ lung de minim 20 de caractere, generat random +
-    * un constructor care primește: un String numit ''​firstName'',​ un String numit ''​lastName''​ și un int numit ''​age''​  +
-    * o metodă ''​getPassword()''​ care va returna parola  +
-      * Parola se construiește concatenand următoarele șiruri:  +
-        * șirul format din ultimele ''​(age % 3)''​ litere din firstName +
-        * un șir random de lungime MAGIC_NUMBER,​ generat cu ''​RandomStringGenerator''​ și cu un alfabet obținut din 10 caractere obținute random din MAGIC_STRING +
-        * și șirul format prin conversia la String a numărului (age + lungimea lui lastName). +
-    * Pentru subșiruri și alte metode utile consultați documentația clasei [[http://​docs.oracle.com/​javase/​8/​docs/​api/​java/​lang/​String.html ​String]] +
- +
-== Resurse ==+
 * <​html><​a class="​media mediafile mf_pdf"​ href="?​do=export_pdf">​PDF laborator</​a></​html>​ * <​html><​a class="​media mediafile mf_pdf"​ href="?​do=export_pdf">​PDF laborator</​a></​html>​
 == Referințe == == Referințe ==
Line 441: Line 374:
 * [[http://​www.javaworld.com/​article/​2077424/​learn-java/​does-java-pass-by-reference-or-pass-by-value.html | Java pass by reference or pass by value]] * [[http://​www.javaworld.com/​article/​2077424/​learn-java/​does-java-pass-by-reference-or-pass-by-value.html | Java pass by reference or pass by value]]
 * [[http://​docs.oracle.com/​javase/​tutorial/​java/​javaOO/​thiskey.html | Using the "​this"​ Keyword]] * [[http://​docs.oracle.com/​javase/​tutorial/​java/​javaOO/​thiskey.html | Using the "​this"​ Keyword]]
-* [[http://​en.wikipedia.org/​wiki/​Final_(Java) | Final Keyword in Java]] 
-* [[http://​www.javatpoint.com/​static-keyword-in-java | Static Keyword explained]] 
 * [[http://​docs.oracle.com/​javase/​7/​docs/​api/​java/​lang/​String.html | String Class]] * [[http://​docs.oracle.com/​javase/​7/​docs/​api/​java/​lang/​String.html | String Class]]
laboratoare/constructori-referinte.1538989849.txt.gz · Last modified: 2018/10/08 12:10 by Andrei Vasiliu