OOP: Java 6.Gy: Java osztályok Definíció, static, túlterhelés 45/1 B ITv: MAN 2019.03.18
Feladat Készítsen egy Alkalmazott osztályt saját csomagban, név, kor és fizetés adatokkal. Legyen egy osztályszintű adattagja a nyugdíjkorhatár tárolására, értéke kezdetben legyen 65. Figyelem! A static adattag kezelése csak static metódusban történhet. Legyen 2 konstruktora. Az egyik a paraméterként kapott név, kor és fizetés értékekkel inicializálja az adattagokat. A másiknak csak a nevet és a kort kell megadni, a fizetés 10000*kor. A második konstruktor használja fel az elsőt. Legyen metódusa, amely visszadja hány éve van még nyugdíjig. Legyen metódusa, amely String-be összefűzve adja vissza az Alkalmazott adatait, hozzáfűzve a nyugdíjig hátralevő éveinek számát is (tostring() felüldefiniálása). Legyen metódusa, amely a paraméterként kapott két Alkalmazott közül azt adja vissza, amelyiknek több éve van még hátra a nyugdíjig. Legyen metódusa, amely a paraméterként kapott értékre állítja be a nyugdíjkorhatárt. 45/2
1 45/3
Konstruktor létrehozása 1 2 3 Source\Generate Constructor using Fields 4 5 Oda fog kerülni a konstruktor, ahol a kurzor áll! 45/4
Getterek, setterek létrehozása 4 1 2 Source\Generate Getters and Setters 3 Oda fognak kerülni a metódusok, ahol a kurzor áll! 45/5
Az Employee osztály kódja package emp; public class Employee_a { private String name; private int age; private long salary; private static int retirementage = 65; public Employee_a(String name, int age, long salary) { this.name = name; this.age = age; Konstruktor 1. this.salary = salary; public Employee_a(String name, int age) { this(name, age, 10000*age); Konstruktor 2. Hívja Konstruktor 1.-et public int yearsuntilretirement() { return retirementage - this.getage(); 45/6 Példány adattagok Osztály adattag static this retirementage - age;
Az Employee osztály kódja public String tostring() { return name + ", " + age + ", Fizetése: " + salary + " Ft/hó, Nyugdíjig hátralévő évek száma: " + yearsuntilretirement(); public static Employee_a getyoungeremployee( Employee_a employee1, Employee_a employee2) { if (employee1.yearsuntilretirement() > employee2.yearsuntilretirement()) { return employee1; Osztály metódus static else return employee2; public String getname() { return name; public void setname(string name) { this.name = name; 45/7
Az Employee osztály kódja public int getage() { return age; public void setage(int age) { this.age = age; public long getsalary() { return salary; public void setsalary(long salary) { this.salary = salary; public static int getretirementage() { return retirementage; public static void setretirementage(int age) { retirementage = age; 45/8
Feladat Készítsen egy futtatható osztályt ugyanebben a csomagban, amely beolvas n számú alkalmazottat egy tömbbe. Írja ki az alkalmazottak adatait, majd módosítsa a nyugdíjkorhatárt és újra írja ki az alkalmazottak adatait. Írja ki azon alkalmazottak adatait, akiknek 5 évnél kevesebb van még hátra nyugdíjig. Írja ki azoknak az alkalmazottaknak az adatait, akiknek az átlagnál több éve van még hátra nyugdíjig. Rendezze az alkalmazottak tömbjét a nyugdíjig hátralévő évek alapján növekvő, majd pedig csökkenő sorrendbe. 45/9
Az EmployeeTest osztály kódja package emp; import java.util.scanner; public class EmployeeTest_a { public static void main(string[] args) { 45/10 Scanner input = new Scanner(System.in); System.out.println("Number of employees: "); int numberofemployees = input.nextint(); input.nextline(); Employee_a[] employeearray= new Employee_a[numberOfEmployees]; for (int i = 0; i < employeearray.length; i++) { System.out.println( (i+1) + ". employee: "); System.out.println("Name: "); String name = input.nextline(); System.out.println("Age: "); int age = input.nextint(); System.out.println("Salary: "); long salary = input.nextlong(); input.nextline(); employeearray[i] = new Employee_a(name, age, salary);
Az EmployeeTest osztály kódja listemployeearray(employeearray); Employee_a.setRetirementAge(67); listemployeearray(employeearray); System.out.println("Nyugdíjig több mint 5 év van hátra: "); for(employee_a employee: employeearray) { if (employee.yearsuntilretirement() < 5) System.out.println(employee); int avg = avgyearsuntilretirement(employeearray); System.out.println("Nyugdíjig hátralevő évek átlaga: " + avg); for(employee_a employee: employeearray) { if (employee.yearsuntilretirement() > avg) System.out.println(employee); 45/11
Az EmployeeTest osztály kódja //Nyugdíjig hátralévő évek alapján növekvő rendezés, listázás System.out.println("Rendezett lista: "); sortemployeearray(employeearray); listemployeearray(employeearray); //Fordított sorrendű kiírás System.out.println("Rendezett lista fordítva: "); for(int i=employeearray.length-1; i>=0; i--) { System.out.println(employeeArray[i]); //== End of main private static void listemployeearray( Employee_a[] employeearray) { for(employee_a employee: employeearray) { System.out.println(employee); 45/12
Az EmployeeTest osztály kódja public static int avgyearsuntilretirement( Employee_a[] employeearray) { int avg = 0; for(employee_a employee: employeearray) { avg += employee.yearsuntilretirement(); avg = Math.round((float)avg / employeearray.length); return avg; 45/13
Az EmployeeTest osztály kódja private static void sortemployeearray( Employee_a[] employeearray) { for(int i=0; i<employeearray.length; i++) { int minindex = i; for(int j=i+1; j<employeearray.length; j++) { if (employeearray[j].yearsuntilretirement() < employeearray[minindex].yearsuntilretirement()) { minindex = j; //Helycsere, ha szükséges if (minindex!= i) { Employee_a tmp = employeearray[i]; employeearray[i] = employeearray[minindex]; employeearray[minindex] = tmp; //== End of Class 45/14
Az EmployeeTest osztály kódja Number of employees: 3 1. employee: Name: Kis Jenőke Age: 37 Salary: 350000 2. employee: Name: Nagy Bendegúz Age: 45 Salary: 220000 3. employee: Name: Kő Emil Age: 25 Salary: 400000 Kis Jenőke, 37, Fizetése: 350000 Ft/hó, Nyugdíjig hátralévő évek száma: 28 Nagy Bendegúz, 45, Fizetése: 220000 Ft/hó, Nyugdíjig hátralévő évek száma: 20 Kő Emil, 25, Fizetése: 400000 Ft/hó, Nyugdíjig hátralévő évek száma: 40 45/15
Az EmployeeTest osztály kódja Kis Jenőke, 37, Fizetése: 350000 Ft/hó, Nyugdíjig hátralévő évek száma: 30 Nagy Bendegúz, 45, Fizetése: 220000 Ft/hó, Nyugdíjig hátralévő évek száma: 22 Kő Emil, 25, Fizetése: 400000 Ft/hó, Nyugdíjig hátralévő évek száma: 42 Nyugdíjig több mint 5 év van hátra: Nyugdíjig hátralevő évek átlaga: 31 Kő Emil, 25, Fizetése: 400000 Ft/hó, Nyugdíjig hátralévő évek száma: 42 Rendezett lista: Nagy Bendegúz, 45, Fizetése: 220000 Ft/hó, Nyugdíjig hátralévő évek száma: 22 Kis Jenőke, 37, Fizetése: 350000 Ft/hó, Nyugdíjig hátralévő évek száma: 30 Kő Emil, 25, Fizetése: 400000 Ft/hó, Nyugdíjig hátralévő évek száma: 42 Rendezett lista fordítva: Kő Emil, 25, Fizetése: 400000 Ft/hó, Nyugdíjig hátralévő évek száma: 42 Kis Jenőke, 37, Fizetése: 350000 Ft/hó, Nyugdíjig hátralévő évek száma: 30 Nagy Bendegúz, 45, Fizetése: 220000 Ft/hó, Nyugdíjig hátralévő évek száma: 22 45/16
Feladat Módosítsa az Alkalmazott osztály definícióját úgy, hogy ne az alkalmazott korát, hanem a születési dátumát tároljuk. A korát az aktuális év és a születési év különbségeként számítjuk. Java 8- ban: import java.time.localdate; LocalDate birthday = LocalDate.of(1998,5,10); //y,m,d LocalDate currentdate = java.time.localdate.now(); int currentyear = currentdate.getyear(); A nyugdíjkorhatár most legyen konstans (final). Így setter metódusa nem lehet. 45/17
Feladat Függvénytúlterhelés: a konstruktorból két változatot készítsen. Az egyik változat az alkalmazott nevét és 3 int paramétert kapjon (év, hónap, nap); A másik az alkalmazott nevét, egy int, egy sztring és még egy int paraméter felhasználásával adjon értéket a név és a születésnap adattagnak. A másik konstruktor paramétere legyen az alkalmazott neve, a születési idő évszáma, a hónap magyar neve, és a nap száma (Tulipán Balázs, 1995, március, 15). A fizetést a 10000*kor képlettel számítsa mindkét konstruktorban. 45/18
Feladat A LocalDate.of() dátum típust előállító metódus 3 int értéket vár. Ezért a hónap nevét számmá kell konvertálni. A születési dátum kiírásához a másik irányú konverzióra lesz szükség. Írjon olyan, az Alkalmazott objektum adatait kiíró metódus, amely az input paraméter függvényében (String: "age" vagy "birthday") Stringbe összefűzve az Alkalmazott nevét és korát; ill. az Alkalmazott nevét és születésnapját írja ki. A hónap neve magyarul jelenjen meg (Kiss Tamás, 2008. március 12.). Egy LocalDate típusú adattag év, hónap és nap komponenseinek lekérdezése: int year = birthday.getyear(); String month = birthday.getmonth().name(); int monthvalue = birthday.getmonthvalue(); int day = birthday.getdayofmonth(); 45/19
Feladat A getmonth().name() metódus a hónap angol nevét adja vissza. Írjon konverziós metódust, amely a hónap sorszámának ismeretében visszaadja a magyar hónapnevet. A magyar hónapneveket osztályszintű adattagként, 13 elemű String tömbben tároljuk, ahol a 0. indexű elemet nem használjuk. A tömb elemeit osztályszintű inicializáló blokkban adja meg. 45/20
Feladat private static String[] monthnames; static { monthnames = new String[13]; monthnames[0] = " "; monthnames[1] = "január"; monthnames[2] = "február"; monthnames[3] = "március"; monthnames[4] = "április"; monthnames[5] = "május"; monthnames[6] = "június"; monthnames[7] = "július"; monthnames[8] = "augusztus"; monthnames[9] = "szeptember"; monthnames[10] = "október"; monthnames[11] = "november"; monthnames[12] = "december"; 45/21 A tömb indexe megegyezik az adott hónap sorszámával, ezt lehet felhasználni a hónap száma és neve közti konverzióhoz.
Feladat A monthnames tömböt használó metódusok: public String convertmonthvalue(int monthvalue) { return monthnames[monthvalue]; A hónap számából előállítja a hónap nevét public int convertmonthname(string monthname) { for(int i=1; i<monthnames.length; i++) { if (monthnames[i].equalsignorecase(monthname)) return i; return 0; A hónap nevéből előállítja a hónap sorszámát equalsignorecase A kis- és nagybetűk nem különböztetik meg a stringeket. Ha hibás a bejövő hónapnév, 0-t ad eredményül. 45/22
Az Employee osztály kódja package emp; import java.time.localdate; public class Employee_b { private String name; private LocalDate birthday; private long salary; //Konstans: értéke nem változtatható meg, setter metódusa nem lehet private static final int retirementage = 65; private static String[] monthnames; 45/23
Az Employee osztály kódja private static String[] monthnames; //Inicializáló blokk static { monthnames = new String[13]; monthnames[0] = " "; monthnames[1] = "január"; monthnames[2] = "február"; monthnames[3] = "március"; monthnames[4] = "április"; monthnames[5] = "május"; monthnames[6] = "június"; monthnames[7] = "július"; monthnames[8] = "augusztus"; monthnames[9] = "szeptember"; monthnames[10] = "október"; monthnames[11] = "november"; monthnames[12] = "december"; 45/24 Javaban csak példányszintű konstruktor létezik, osztályszintű nincs, ezt pótolja az osztályszintű inicializáló blokk Jellemzői: Több is lehet belőle egy osztályban Az osztály betöltődésekor (az osztályra történő első hivatkozáskor) fut le Szerepe: a statikus tagok inicializálása, bonyolultabb esetben. Pl. egy tömb elemeinek inicializálása A "statikus kontextus" része, ezért nem lehet benne példányszintű tagokra hivatkozni
Az Employee osztály kódja public Employee_b(String name, LocalDate birthday, long salary) { this.name = name; this.birthday = birthday; this.salary = salary; Konstruktor, komplett dátumot kap //A konstruktorban a getage() példányszintű metódus nem hívható public Employee_b(String name, int year, int month, int day) { this.name = name; this.birthday = LocalDate.of(year, month, day); this.salary = 10000*(LocalDate.now().getYear()- birthday.getyear()); Konstruktor, (év, hónap, nap) alakban kap dátumot 45/25
Az Employee osztály kódja public Employee_b(String name, int year, String month, int day) { this.name = name; int monthvalue; if(convertmonthname(month)==0) monthvalue = 1; //default: január else monthvalue = convertmonthname(month); this.birthday = LocalDate.of(year, monthvalue, day); this.salary = 10000*(LocalDate.now().getYear()- birthday.getyear()); Konstruktor, (év, magyar hónapnév, nap) alakban kap dátumot 45/26
Az Employee osztály kódja public int yearsuntilretirement() { return retirementage - this.getage(); public int getage() { return LocalDate.now().getYear()-birthday.getYear(); public String displayinfo(string str) { String info = " "; switch(str) { case "age" : info = name + ", kora: " + getage() + " év"; break; case "birthday" : info = name + ", szül.: " + gethunbirthday(); 45/27 return info; A bemenő string függvényében ad vissza szöveges információt
Az Employee osztály kódja public String gethunbirthday() { int year = birthday.getyear(); int monthvalue = birthday.getmonthvalue(); String monthname = convertmonthvalue(monthvalue); int day = birthday.getdayofmonth(); return year + ". " + monthname + " " + day + "."; public String convertmonthvalue(int monthvalue) { return monthnames[monthvalue]; A hónap számából előállítja a hónap nevét public int convertmonthname(string monthname) { for(int i=1; i<monthnames.length; i++) { if (monthnames[i].equalsignorecase(monthname)) return i; return 0; A hónap nevéből előállítja a hónap sorszámát 45/28
Az Employee osztály kódja @Override public String tostring() { return name + ", " + birthday + ", Fizetése: " + salary + " Ft/hó, Nyugdíjig hátralévő évek száma: " + yearsuntilretirement(); //Getter, setter methods public String getname() { return name; public void setname(string name) { this.name = name; public long getsalary() { return salary; 45/29
Az Employee osztály kódja public void setsalary(long salary) { this.salary = salary; public LocalDate getbirthday() { return birthday; public void setbirthday(localdate day) { this.birthday = day; public static int getretirementage() { return retirementage; 45/30
Az EmployeeTest osztály kódja Feladat: Módosítsa a futtatható osztályt ennek megfelelően és próbálja ki az új metódusokat! package emp; import java.time.localdate; import java.util.scanner; public class EmployeeTest_b { public static void main(string[] args) { Scanner input = new Scanner(System.in); System.out.println("Number of employees: "); int numberofemployees = input.nextint(); input.nextline(); Employee_b[] employeearray= new Employee_b[numberOfEmployees]; 45/31
Az EmployeeTest osztály kódja 45/32 for (int i = 0; i < employeearray.length; i++) { System.out.println( (i+1) + ". employee: "); System.out.println("Name: "); String name = input.nextline(); System.out.println("Birthday: "); String instring = input.nextline(); String[] birthdaycomponents = instring.split("/"); int year=0, month=0, day=0; try { year = Integer.parseInt(birthdayComponents[0]); day = Integer.parseInt(birthdayComponents[2]); month = Integer.parseInt(birthdayComponents[1]); employeearray[i] = new Employee_b(name, year, month, day); catch (Exception NumberFormatException) { if (month==0) employeearray[i] = new Employee_b(name, year, birthdaycomponents[1], day);
Az EmployeeTest osztály kódja listemployeearray(employeearray); //== End of main private static void listemployeearray( Employee_b[] employeearray) { for(employee_b employee: employeearray) { System.out.println(employee); System.out.println(employee.displayInfo("birthday")); System.out.println(employee.displayInfo("age")); //== End of class 45/33
Feladat Készítsen egy Szám osztályt a mypackage.first nevű csomagban, amelynek: Van egy osztályszintű konstans adattagja 0.001 értékkel egy tűrés tárolására. Legyen egy másik private adattagja egy valós szám tárolására. Legyen konstruktora, amely a paraméterként kapott valós számmal inicializálja az adattagot. Legyen egy metódusa, amely igazat ad, ha a valós szám adattagnak a paraméterként kapott számtól való eltérése a tűrésen belül van. Legyen getter, setter metódusa a valós szám adattagra. 45/34
RealNum 45/35
A RealNum osztály kódja package mypackage.first; public class RealNum { private static final double tolerance = 0.001; private double realnum; public RealNum(double realnum) { this.realnum = realnum; public boolean isintolerancerange(double num) { if (Math.abs(realNum-num) < tolerance) { return true; else return false; public double getrealnum() { return realnum; public void setrealnum(double realnum) { this.realnum = realnum; 45/36
Feladat Készítsen egy futtatható osztályt a mypackage.second nevű csomagban, amelyben: Létrehoz egy Számot, melynek értéke 0-1 közötti intervallumba esik, és eltárolja egy final lokális változóban. Generáljon ciklusban 0-1 közötti valós számokat és írja ki azokat egész addig, amíg egyezőt nem talál a létrehozott Számmal (különbségük a tűrésen belül van). Írja ki hányadiknak állította elő ezt a számot. Próbálja ki, hogy meg tudja-e változtatni a Szám adattagjának értékét. Próbálja ki, hogy meg tudja-e változtatni a referenciájának az értékét. 45/37
A RealNumTest osztály kódja package mypackage.second; //imports classes only in package mypackage and NOT in the subpackage first import mypackage.*; //imports classes in package mypackage.first import mypackage.first.*; public class RealNumTest { public static void main(string[] args) { //final mypackage.first.realnum realnum = new mypackage.first.realnum(0.25); final RealNum realnum = new RealNum(0.25); int counter = 0; boolean found = false; 45/38
A RealNumTest osztály kódja while (!found) { double tmprealnum = Math.random(); System.out.println(tmpRealNum); counter++; if (realnum.isintolerancerange(tmprealnum)) { found = true; System.out.println("Number of generated numbers: " + counter); //Teszt: a RealNum osztály adattagjának értéke megváltoztatható realnum.setrealnum(0.5); //Teszt: a final lokális változó értékét nem lehet módosítani //realnum = new RealNum(0.12); //== End of main 0.3982150463212395 0.4909738030073373 //== End of class 0.45470290241425126 0.40748999869033165 0.007511541205290628 45/39 Number of generated numbers: 43
Házi feladat A korábbi gyakorlatokon elkészített Könyv osztályt helyezze át saját csomagba. A szerző, cím és ár adattagok változatlanok. Egészítse ki egy oldalszám adattaggal és egy kiadó osztályszintű adattaggal, melynek kezdőértéke Móra. A megjelenés éve adattag legyen konstans, az objektum létrehozás éve. Módosítsa a 2 konstruktort ennek megfelelően. Módosítsa azt a metódust, amely String-ben összefűzve adja vissza a könyv adatait. Írjon osztályszintű metódust, amely két paraméterként kapott könyv közül a hosszabbat adja vissza. Írjon metódust, amely igazat ad vissza, ha a könyv oldalszáma páros. 45/40
Házi feladat Ebben a csomagban készítsen futtatható osztályt, amelyben beolvas n darab könyvet egy tömbbe. Írja ki a leghosszabb könyv adatait. Írja ki a leghosszabb páros oldalszámú könyv adatait. Algoritmus: 1. Létrehozunk egy maxindex változót, melynek értéke -1. 2. Megkeressük az első páros oldalszámú könyvet. Ennek az indexét eltároljuk a maxindex változóban. 3. Ha a maxindex >= 0 (azaz találtunk páros oldalszámú könyvet), akkor a maxindex sorszámtól kezdve maximum kereső eljárás. 45/41
Házi feladat Írja ki, hogy melyik szerzőnek hány darab könyve jelent meg. Algoritmus: 1. Veszem a következő könyvet. Ha a szerzője megegyezik egy korábban már vizsgált könyv szerzőjével, akkor továbblépek a következő könyvre. 2. Ha ez az adott szerző első előfordulása, akkor létrehozok egy számláló változót 1 értékkel és kiírom a szerző nevét. 3. Az aktuális indextől kezdve nézem a könyvek szerzőit, ha azonos szerzőt találok, növelem eggyel a számlálót. 4. A végén kiírom a számláló értékét. Ugyanezeket a feladatokat oldja meg úgy is, hogy a futtatható osztályt másik csomagban definiálja. 45/42
1. Kérdés a 850-ből: Mire használható a failstheexam() metódus? Megbukni a vizsgán Megbukni a vizsgán Megbukni a vizsgán Megbukni a vizsgán OK 45/43
Feladat Osztály létrehozása adott csomagban, adott adattagokkal, adott metódusokkal: mindenféle adattagok (szöveg, szám, dátum) több (egymást hívó) konstruktor tostring() felüldefiniálása metódusok készítése: bemenő paraméterek: egyszerű változók, osztály típusúak Programosztály létrehozása (esetleg eltérő csomagban): Osztály típusú tömb létrehozása, Elemek beolvasása, generálása Tömb adatainak kiírása (for, for each) (feltételekkel, esetleg visszafelé) Algoritmusok elvégzése a tömbön, aztán adatkiírás 45/44
VÉGE VÉGE 45/45