-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMoreInheritance.java
More file actions
347 lines (274 loc) · 13.2 KB
/
Copy pathMoreInheritance.java
File metadata and controls
347 lines (274 loc) · 13.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
import java.*;
import java.util.*;
interface A {
}
interface B {
}
/*
* o interfata poate sa extinda una sau mai multe interfete in acelasi timp
*/
interface C extends A, B {
}
interface D extends A {
}
//--------------------------------------------------------------------------------------------------------------------------//
interface IAnimal {
int magicValue = 69; // campurile sunt by default publice si statice
void makeSound();
static int anotherMagicValue = 420; // e ca mai sus, doar ca e explicita
// in interfata, metodele sunt by default publice (altfel ar fi irelevant, caci scopul e ca aceste metode sa fie accesate din afara interfetei pentru implementare)
static void muie() {
System.out.println("Coraci este un profesor model");
}
// pe scurt, intr-o interfata putem avea membri statici care se comporta normal ca intr-o clasa
}
abstract class Animal implements IAnimal {
protected String origin;
// un membru protected e vizibil in clasa in care se afla (duuuh, e logic)
//si in clasele mostenitoare, unde acesta (fiind mostenit de ele) este privit ca un membru privat
public String name;
public Animal (String origin, String name) {
this.origin = origin;
this.name = name;
}
// metoda makeSound() din interfata IAnimal este tratata by default ca o metoda abstracta in clasa abstracta care o implementeaza
public abstract void doSomething(); // metoda abstracta
// intr-o clasa abstracta putem sa avem metode deja implementate
// chiar mai mult, tehnic, putem sa avem toate metodele dintr-o clasa abstracta deja implementate, insa nu mai are niciun rost ca clasa (ne place cacofonia)
// sa mai fie abstracta
public void doStuff() {
System.out.println("Teoria sistemelor e cea mai tare materie! <3");
}
}
class StrangeAnimal implements IAnimal {
// fiind o clasa normala, deci nu abstracta (obvious), trebuie neaparat sa implementam metoda makeSound
public void makeSound() {
System.out.println("Coraci este o persoana cinstita, care nu fura"); // vrajeala
}
}
/*
* o clasa poate:
* sa implementeze mai multe interfete in acelasi timp
* sa extinda doar o clasa o data(vezi ambiguitate)
* sa extinda o clasa si sa implementeze interfete in acelasi timp
* o clasa nu poate extinde mai multe clase in acelasi timp din cauza ambiguitatii, in sensul ca putem sa avem 2 clase, X si Y, care sa aiba o metoda, sa zicem,
* public void servitaLaTS(), cu functionalitate diferita in ambele clase, ceea ce duce la ambiguitate, caci clasa Z, care ar vrea sa mosteneasca X si Y, s-ar gandi asa:
* boss, le mostenesc pe X si Y, ambele au o metoda servitaLaTS(), insa in ambele clase se comporta diferit si nu stiu nu am cum sa aleg --> nu pot mosteni 2 clase in acelasi timp
*/
class Dog extends Animal {
public Dog (String name, String origin) {
super (origin, name); // super, intr-o clasa copil, se refera la clasa parinte (e ca this-ul, doar ca face referire la obiectul din clasa parinte, nu cea actuala \ copil)
}
// trebuie sa implementam doSomething din clasa abstracta Animal
public void doSomething() {
System.out.println("I like to eat my own poop, because I'm a stupid dog");
}
// acum trebuie sa implementez makeSound din IAnimal
public void makeSound() {
System.out.println("Ham ham haaaaaam un bajetzel");
}
// pot sa adaug metode specifice clasei
public void shakeDoggy() {
System.out.println("Shake shake");
}
}
class Cat extends Animal {
public Cat (String name, String origin) {
super (name, origin);
}
// trebuie sa implementam doSomething din clasa abstracta Animal
public void doSomething() {
System.out.println("FEED ME HOOMAN");
}
// acum trebuie sa implementez makeSound din IAnimal
public void makeSound() {
System.out.println("MEOOOOOOWWWWWW");
}
// vrem sa suprascriem o metoda din clasa parinte in clasa copil
@Override
public void doStuff() {
super.doStuff(); // asa apelam o metoda din clasa parinte
System.out.println("Origin with super: " + super.origin);
System.out.println("Origin with this: " + this.origin);
// campurile unei clase sunt mostenite -> le putem accesa cu this (numai daca nu sunt private in clasa parinte)
System.out.println("I do nothing, just sleep, eat, shit and repeat");
}
}
/*
* intre clasa Cat (sau Dog) si Animal exista o relatie de tip Is-A (Cat / Dog este un Animal), de asemenea intre Animal si IAnimal exista o relatie de tip Is-A
* pe scurt o relatie de tip Is-A e construita prin mostenire (extindere de clasa sau implementare de interfata)
*/
class Human {
private Cat pussy;
private Dog doggy; // wink wink
public Human (Cat pussy, Dog doggy) {
this.pussy = pussy;
this.doggy = doggy;
}
public Cat getPussy() {
return pussy;
}
// o metoda final nu poate fi suprascrisa in nicio clasa mostenitoare / subclasa
final public Dog getDoggy() {
return doggy;
}
}
/*
* intre clasa Human si clasa Cat (si Dog) exista o relatie de tip Has-A (agregare), in sensul ca Human are un Cat (si un Dog - suna aiurea in romana, csf)
*/
/*
* o clasa poate sa extinda o alta clasa si in acelasi timp sa implementeze interfete
*************************************************************************************
* o clasa final este o clasa ce nu poate fi mostenita / extinsa deloc
*/
final class Decebal extends Human implements A, B {
public Decebal (Cat pussy, Dog doggy) {
super(pussy, doggy);
}
}
/*
class Ciobanu extends Decebal {
// vom avea eroare daca facem asa
} */
// ***********************************************************************
// Comparator vs Comparable - 2 interfete predefinite in Java, folosite pentru compararea a 2 obiecte, in principiu pentru sortarea de colectii
/*
* Comparator - o clasa ce implementeaza interfata Comparator este folosita ca un instrument de comparare a 2 obiecte, adica cand vrem sa dorim
* sortarea a unei colectii in functie de un criteriu de comparare (de exemplu sortarea unei liste de studenti in ordinea crescatoare a mediei),
* vom da ca parametru la metoda Collections.sort si un obiect care reprezinta instanta clasei care implementeaza Comparator
*/
class Student {
private double medie;
private String nume, prenume;
public Student (String nume, String prenume, double medie) {
this.medie = medie;
this.nume = nume;
this.prenume = prenume;
}
public String toString() {
return "Student: " + prenume + " " + nume + " -> " + medie;
}
public double getMedie() {
return medie;
}
public String getNume() {
return nume;
}
public String getPrenume() {
return prenume;
}
}
// o clasa ce compara studentii intre ei -> criteriu de sortare
// + aici avem warning cu raw types (genericitate)
class StudentComparator implements Comparator {
@Override // e esential sa specificam Override
public int compare (Object o1, Object o2) { // -> nu am tipizat Comparator aici -> compare primeste Object ca parametri by default
Student s1 = (Student) o1;
Student s2 = (Student) o2;
// daca au mediile egale + e o varianta ok de a compara numere double in Java -> o recomand pe asta
if (Double.compare(s1.getMedie(), s2.getMedie()) == 0) {
return s1.getNume().compareTo(s2.getNume()); // ordonam crescator dupa nume -> descrescator era s2...compareTo(s1...)
}
return Double.compare(s1.getMedie(), s2.getMedie()); // ordonam crescator dupa medie
} // compare -> compara 2 obiecte - returneaza 0 (egale), > / < 0 (crescator / descrescator)
}
// tipizam Comparator cu Student -> compare primeste Student ca parametri
class StudentComparator2 implements Comparator<Student> {
@Override // e esential sa specificam Override
public int compare (Student s1, Student s2) {
// daca au mediile egale + e o varianta ok de a compara numere double in Java -> o recomand pe asta
if (Double.compare(s1.getMedie(), s2.getMedie()) == 0) {
return s1.getNume().compareTo(s2.getNume()); // ordonam descrescator dupa nume
}
return Double.compare(s2.getMedie(), s1.getMedie()); // ordonam descrescator dupa medie
}
}
// Comparable -> un obiect ce este o instanta a unei clase ce implementeaza Comparable este comparabila (sesizati cu limba in obraz) cu un alt obiect care reprezinta o instanta a aceleiasi clase
// precum Comparator, este folosit drept criteriu de comparare pentru sortare, insa diferenta fata de Comparator este ca la sortarea cu Collections.sort nu mai e nevoie sa
// dam ca parametru un criteriu de comparare (adica un Comparator), sortarea se face dupa criteriul specificat in metoda compareTo
// treaba cu tipizarea interfetei e fix ca mai sus
class Star implements Comparable {
private String nume, prenume;
private int varsta;
public Star (String nume, String prenume, int varsta) {
this.varsta = varsta;
this.nume = nume;
this.prenume = prenume;
}
private String getNume() {
return nume;
}
private String getPrenume() {
return prenume;
}
public int getVarsta() {
return varsta;
}
@Override
public int compareTo (Object obj) {
Star star = (Star) obj;
// daca au varsta egala - sortam crescator dupa nume
if (this.getVarsta() == star.getVarsta())
return this.getNume().compareTo(star.getNume());
return this.getVarsta() - star.getVarsta(); // crescator dupa varsta
}
public String toString () {
return "Star: " + prenume + " " + nume + " -> " + varsta + " de ani";
}
}
public class MoreInheritance {
public static void main (String[] main) {
// asa construim clase anonime (nu tine de labul asta, dar are legatura cu mostenirea), adica construim clase fara nume prin extinderea altei clase sau prin implementarea unei interfete
IAnimal pl = new IAnimal() {
public void makeSound() {
System.out.println("AYYY PAPI HARDEEER");
}
};
System.out.println(pl.magicValue); // warning prin faptul ca accesam un membru static prin obiect.cevaStatic
System.out.println(IAnimal.anotherMagicValue);
pl.makeSound();
/*
* nu putem instantia o clasa abstracta sau o interfata, adica, in cazul nostru, sa scriem direct Animal cezar = new Animal(); sau IAnimal saracin = new IAnimal();
* insa mai jos putem sa facem o chestie, profitand de relatia Is-A dintre clase
*/
Animal kitty = new Cat("Malone", "Focsani <3"); // I <3 Focsani
Animal vagabond = new Dog("Cockciorba", "Panciu");
// in cazul de mai sus, vom avea obiecte de tip Animal, insa instantiate ca Cat (cacacacaca) sau ca Dog si nu putem sa folosim metode specifice unei anumite clase
// vagabond.shakeDoggy(); //-> nu merge, caci vagabond este un Animal instantiat ca Dog, deci nu e Dog, asadar nu pot apela shakeDoggy
// insa putem sa facem castare
((Dog)vagabond).shakeDoggy(); // iar acum vagabond este Dog, deci pot apela shakeDoggy
kitty.doStuff(); // se apeleaza doStuff din Animal
((Cat)kitty).doStuff(); // se apeleaza doStuff din Cat
Dog javra = new Dog("Coraci", "Puscarie");
Cat pussy = new Cat("Tibi <3", "Constanta");
Human jmek = new Human(pussy, javra);
// Comparator
ArrayList<Student> list = new ArrayList<>(); // ArrayList este o colectie, vom invata despre colectii in labul 7
// inainte de sortare
list.add(new Student("Mihu", "Andrei", 8.50));
list.add(new Student("Raducanu", "Constantin", 9.20));
list.add(new Student("Mihalache", "Florin", 8.50));
System.out.println(list);
StudentComparator comp = new StudentComparator(); // criterii de comparare
StudentComparator2 comp2 = new StudentComparator2();
Collections.sort(list, comp); // sortam crescator dupa medie
// sortare crescatoare
System.out.println(list);
Collections.sort(list, comp2); // sortam descrescator dupa medie
// sortare descrescatoare
System.out.println(list);
// asadar, Comparator il folosim daca pur si simplu sa ordonam o colectie la un moment dat dupa un anumit criteriu
// Comparable
ArrayList<Star> stars = new ArrayList<>();
stars.add(new Star("Kent", "Nelly", 21));
stars.add(new Star("Romain", "Sandra", 40));
stars.add(new Star("Mocanu", "Madalina", 21));
stars.add(new Star("Bunny", "Sweet", 25));
stars.add(new Star("Plugaru", "Alina", 30));
// neordonat
System.out.println(stars);
Collections.sort(stars); // deja avem criteriul de sortare
// ordonat
System.out.println(stars);
}
}