740 likes | 928 Views
Angster Erzsébet: OO tervezés és programozás, Java II. kötet alapján. Programozási technológia. Készítette: Andor Gergely Ellenőrizte: Dr. Szelezsán János Jóváhagyta: Lengyel Zsuzsánna. I. Objektumorientált technikák II. Grafikus felhasználói interfész III. Állománykezelés
E N D
Angster Erzsébet: OO tervezés és programozás, Java II. kötet alapján Programozási technológia • Készítette: Andor Gergely • Ellenőrizte: Dr. Szelezsán János • Jóváhagyta: Lengyel Zsuzsánna
I. Objektumorientált technikák II. Grafikus felhasználói interfész III. Állománykezelés IV. Vegyes technológiák V. Adatszerkezetek, kollekciók Programozási technológia
1. Csomagolás, projektkezelés 2. Öröklődés 3. Interfészek, belső osztályok 4. Kivételkezelés I. Objektumorientált technikák
1. Csomagolás, projektkezelés 1. Csomagolás 2. Projektkezelés a JBuilderben 3. JAR-állomány készítése Java program futtattása I. Objektumorientált technikák
csomag2 csomag1 csomag12 csomag11 Osztaly5 csomag121 Interfesz Osztaly3 Osztaly1 Osztaly4 Osztaly2 Csomagolás Csomag (package) • Összetartozó osztályok és interfészek csoportja • Logikai és fizikai szintű csoportosítás
Projektkönyvtár Projektfájl CsomagApp Célútvonal Forrásútvonal CsomagApp.jpx src classes csomag1 csomag2 csomag1 csomag2 Osztaly5.java Osztaly5.class csomag11 csomag12 csomag11 csomag12 Interfesz.java Osztaly2.java Osztaly4.java Interfesz.class Osztaly1.class Osztaly2.class Osztaly4.class csomag121 csomag121 Osztaly3.java Osztaly3.class Könyvtárstruktúra
Csomag azonosításaUML: csomag1::csomag12::csomag121 Java: csomag1.csomag12.csomag121 Csomag megadásapackage csomag1.csomag12.csomag121; Más csomag importálásaimport csomag1.csomag12.csomag121.Osztaly3; import csomag1.csomag12.csomag121.*;
Csomag elemeinek láthatósága • Osztály vagy interfész láthatósága • publikus (public) • csomagszintű • Osztálytagok (adatok, metódusok) láthatósága • publikus (public , +) • védett (protected , #) • privát (private , -) • csomagszintű • Az öröklési ágon az osztálytagok láthatósága csak bővíthető!
Projektkezelés a JBuilderben Projekt (project) • Egy adott szoftver fejlesztéséhez használt, logikailag összetartozó állományok és környezeti beállítások gyűjteménye • Projektállomány • projektelemek (állományok) listája • projekt tulajdonságai
Projektpanel Tartalompanel Struktúrapanel Üzenetpanel Projektkezelés JBuilderben Projekt (project) • összetartozó osztályok és interfészek csoportja • logikai és fizikai szintű csoportosítás
Java fordítóprogram • Alapútvonalak • kimeneti útvonal – output path • osztályútvonal – class path • forrásútvonal – source path • Példák • 02Oroklodes\HengerProgram\src\compile1.bat:javac -g -nowarn Henger.java • 01Projekt\CsomagApp\make.batjavac -sourcepath src -d classes -classpath . @Files.txt
JAR-állomány készítése JAR (Java ARchive) • Egy Java projekt fájljait tömörítő állomány • Manifest (aláírásfájl, manifest.mf) JAR fájl összeállítása parancssorbóljar cfm CsomagApp.jar meta-inf\manifest.mf –C classes . JAR fájl futtatásajava –jar CsomagApp.jar
2. Öröklődés 1. Az öröklődés fogalma 2. Mintafeladat – Hengerprogram 3. Az objektumreferencia statikus és dinamikus típusa 4. Az utódosztály adatai és kapcsolatai 5. Metódusok felülírása, dinamikus és statikus kötés 6. this és super referenciák 7. this és super konstruktorok – konstruktorok láncolása 8. Polimorfizmus 9. Absztrakt metódus, absztrakt osztály 10. Láthatóság 11. Összefoglalás – metódusok nyomkövetése I. Objektumorientált technikák
Öröklődés Öröklődés(inheritance), kiterjesztés(extension) • Egy meglévő osztály kiterjesztése, továbbfejlesztése • Ősosztály, utódosztály • Egyszeres / többszörös öröklés Az öröklés szabályai • Egy osztályból több osztály is származtatható • Az osztályhierarchia mélysége tetszőleges • Az öröklés tranzitív • A Javában minden osztály implicit őse az Object,és csak egyszeres öröklés van.
Mintafeladat – Hengerprogram • Feladat – Hengerprogram • Különböző hengereket szeretnénk nyilvántartani: • vannak olyan hengerek, amelyek csupán mértani testek. Ezeknek van sugaruk és magasságuk; • vannak rudak (tömör hengerek), melyeknek súlyuk is van; • végül vannak csövek: valamekkora falvastagságú tömör, lyukas hengerek. • Készítsük el a megadott hengerek osztályait! Inicializáláskor a hengereknek értelemszerűen megadhatók a következő adatok: sugár, magasság, fajsúly és falvastagság. A fajsúlyt nem kötelező megadni, az alapértelmezésben legyen 1!
Minden henger legyen képes visszaadni alapadatait, térfogatát és esetleges súlyát! A toString() metódus adja meg az adott henger szöveges reprezentációját! • A fent leírt osztályokból példányosítsunk néhányat, és tegyük bele őket egy konténerbe! Végezzük el a következő feladatokat: • Írjuk ki a hengerek számát, és listázzuk ki a hengerek adatait! • Számítsuk ki a konténerben található összes henger átlag térfogatát! • Listázzuk ki a csövek adatait, adjuk meg a csövek számát és összsúlyukat! • Számoljuk és a program végén írjuk ki a program futása közben született hengerek számát!
Henger -szuletesSzamlalo: int -sugar, magassag: double HengerProgram +Henger(sugar,magassag: double) +getSzuletesSzamlalo: int +getSugar(): double +getMagassag(): double +terfogat(): double +toString(): String * hengerek {Vector} +HengerProgram() +atlagTerfogat(): double +lista(vektor: Vector) +run() +main(...) Rud -fajsuly: double +Rud(sugar,magassag,fajsuly: double) +Rud(sugar,magassag: double) +getFajsuly(): double +suly(): double +toString(): String Cso -falVastagsag: double +Cso(sugar,magassag,fajsuly,falVastagsag: double) +Cso(sugar,magassag,falVastagsag: double) +getFalVastagsag(): double +terfogat(): double +toString(): String Osztálydiagram
class Henger { //... } class Rud extends Henger { //... } class Cso extends Rud { //... } public class HengerProgram { //... }
:Object Object Helytelen! :Henger Henger r : Rud :Rud Rud :Cso Cso Az objektumreferencia statikus és dinamikus típusa • Statikus típus: deklarált osztály • Dinamikus típus: mutatott objektum valódi osztálya
instanceof operátorObject obj = new String("Valami");if (obj instanceof Object) ... // trueif (obj instanceof String) ... // trueif (obj instanceof Integer) ... // falseif ("Semmi" instanceof String) ... // true Automatikus típuskonverzió felfelé (upcasting)String str = "Kakukk";System.out.println(str.toLowerCase()); // OKObject obj = str; // StringObject//System.out.println(obj.toLowerCase()); Fordítási hiba!
Típuskonverzió lefelé (downcasting) Object obj = "Szoveg"; // String ObjectString str = (String)obj; // Object String// String str = obj; Fordítási hiba! Object obj = "Kakas"; // String ObjectInteger iObj = (Integer)obj; // Object Integer (!)System.out.println(iObj.intValue()); // ClassCastException!
Henger -sugar: double -magassag: double r : Rud cso : Cso h : Henger sugar = 0.5 magassag = 4 fajsuly = 2 sugar = 5 magassag = 5 fajsuly = 0.5 falVastagsag = 2 sugar = 1 magassag = 4 Rud -fajsuly: double Cso -falVastagsag: double Az utódosztály adatai és kapcsolatai Példányadatok memóriafoglalása
Hivatkozás az adatokra • Hivatkozás kívülről: publikus, nem takart példányadatokra, illetve osztályadatokra • Hivatkozás osztályból: publikus vagy védett ősadatokra • Adatok takarása • Adatot nem lehet felülírni! • Adat takarása = ugyanolyan nevű másik adat deklarálása
class C2 extends C1 { int a = 2; } class C1 { static String s = "C1 "; int a = 1; int b = 10; } class C3 extends C2 { static String s = "C3 "; int b = 30; public void kiir1() { System.out.println(C1.s+C2.s+s);} //public void kiir2() { System.out.println(C1.a+C2.a+C3.a);} public void kiir3() { System.out.println(super.a+a); } public void kiir4() { System.out.println(super.b+b); } }
Metódus felülírása, dinamikus és statikus kötés Példánymetódus felülírása (overriding) • Egy metódus az utódosztályban felülírható, ha az • nem private • nem final • nem static (példánymetódus) • Dinamikus kötés, futás alatti kötés, késői kötés Osztálymetódus • Az osztály sajátja, nem írható felül • Statikus kötés
m1() obj1:C1 m1() obj2:C2 C1 m1() {m2()} m2() C2 m2() A példánymetódus dinamikus kötése
m1() obj1:C1 m1() obj2:C2 C1 m1() {m2()} m2() C2 m2() Az osztálymetódus statikus kötése
this és super referenciák • A megszólított objektum referenciái • Példánydeklarációk takarása esetén használatosak • Hivatkozás saját (eltakart) adatra this.adat • Hivatkozás ős (eltakart) adatra / metódusra super.adat super.metódus()
Konstruktorok láncolása • Minden osztálynak van saját konstruktora • A konstruktor nem öröklődik, és nem lehet felülírni • Konstruktorhívási lánc • Konstruktorok láncolásának szabályai • Osztályon belül másik konstruktor hívása: this(paraméterek) • A közvetlen ős konstruktor hívása: super(paraméterek) • Minden konstruktorban pontosan egy this() vagy super() hívás legelső utasításként
class C1 { C1(int a) { } } class C2 extends C1 { C2(int a, int b) {super(a);} C2(int a) {this(a,1);} C2() {this(2);} } class C3 extends C2 { C3(int a, int b) { } C3(int a) {this(a,3);} } Példa
class C4 extends C3 { int a; //C4() {super();} // hiba: C3-ban nincs C3() //C4() { } // hiba: C3-ban nincs C3() //C4() {a=1; super(a);} // hiba: super nem első! //C4() {this(); super(5);} // hiba: kettő nem lehet! } public class KonstruktorProba { public static void main (String args[]) { new C3(1); } }
:Rud :Henger :Rud :Henger :Cso terfogat() toString() terfogat() toString() terfogat() toString() :HengerProgram Polimorfizmus
Absztrakt metódus, absztrakt osztály • Absztrakt metódus: üres metódus, mely csak örökítési célt szolgál • Absztrakt osztály: absztrakt metódust tartalmazó, nem példányosítható osztály • Jelölés • UML: dőlt betűvel • Java: abstract class <OsztályAzonosító> { …abstract <metódusAz>(paraméterek); …}
Feladat – FaIdomok • Egy fajátékokat tartalmazó dobozban két féle idom van: gömb és hasáb, különböző méretekben. Készítsünk olyan programot, amellyel nyilvántart-hatjuk különböző idomok adatait! Írjuk ki a következőket: • az összes idom adatait a felvitel sorrendjében; • az idomok összsúlyát; • a gömbök összsúlyát; • a legkisebb és a legnagyobb térfogatú idom típusát és adatait!
idomok java::lang::Comparable java::lang::Object FaIdomok * -idomok {Vector} +FaIdomok() +osszSuly(): double +osszGombSuly(): double +run() +main(...) Idom { abstract } Gomb Hasab -sugar: double -a,b,magassag: double -fajsuly: double = 0.8 +Gomb(sugar:double) +terfogat(): double +toString(): String +Hasab(a,b,magassag:double) +terfogat(): double +toString(): String +terfogat(): double +suly(): double +compareTo(obj:Object): int Osztálydiagram
3. Interfészek, belső osztályok 1. Interfész 2. Belső osztály 3. Névtelen osztály I. Objektumorientált technikák
Interfész • Konstansokat és metódusfejeket definiál • Implementáló osztály: a metódusokat implementálja • Deklarációja:[public] interface <InterfészAzon> [extends <InterfészAzon,...>] { <konstansok, metódusfejek>} • Abstract, nem példányosítható • Egyetlen lehetséges módosítója: public • Konstansok módosítói: public, static, final • Metódusfejek módosítói: public, abstract
Az interfész implementálása • Implementáló osztály: speciális utódja az interfésznek • Nem abstract osztály összes metódust meg kell írniAbstract osztály az utódban befejezhető az implementálás • Egy osztály akárhány interfészt implementálhat! • Az interfész egyes metódusait az implementáló osztály örökölheti is
Az interfész öröklése • Az interfészek örökíthetők • Az utód interfész örökli az ős interfész deklarációit • Az utód interfész implementálásakor implementálnunk kell az ős interfész metódusait is • Egy interfész akárhány interfészt örökölhet! • Értékadási kompatibilitás • Az objektum statikus referenciája lehet interfész típusú • Az implementáló osztály objektuma értékül, illetve paraméterül adható az interfész típusú statikus referenciának
Feladat – Sorok feldolgozása, QueueApp • A sor szekvenciális, csak sorban feldolgozható konténer; csak a végére lehet új elemet tenni, s csak a legelsőnek betett elemet lehet kivenni belőle. • Készítsünk két interfészt: • Az IQueueolyan sor, amely képes a következőkre: • Betesz egy új objektumot a sor végére; • Kiveszi, és rendelkezésre bocsátja a sor legelső objektumát; • Megmondja, hogy a sor üres-e. • Az ICleverQueueokos sor (clever queue), s az előbbieken túl a következőket is tudja: • Kiveszi és megszünteti a sor első n objektumát; • Megadja a sorban álló objektumok számát.
Készítsünk mindkét interfészből egy-egy osztályt! Az ICleverQueue implementációja legyen leszármazottjaaz IQueue implementációjának. • Az interfészeket és az osztályokat tegyük be az extra.util csomagba, hogy később is használhassuk őket! • Végül készítsünk egy programot, amely menüvezérelten végzi a következő funkciókat: • betesz a sorba egy szöveget; • kivesz a sorból egy szöveget (ha van) és ki is írja; • kitöröl a sorból három szöveget, ha van benne annyi!
extra::util java::lang::Object «interfész» IQueue Queue +put(Object) +get(): Object +isEmpty(): boolean +put(Object) +get(): Object +isEmpty(): boolean «interfész» ICleverQueue QueueApp CleverQueue +main(...) +processQueue(ICleverQueue) +remove(int) +size(): int +remove(int) +size(): int Osztálydiagram • Forráskódok Projekt: QueueApp Csomaghierarchia: • QueueApp • extra • util • IQueue • ICleverQueue • Queue • CleverQueue
IQueue.java package extra.util; public interface IQueue { void put(Object o); Object get(); boolean isEmpty(); } ICleverQueue.java package extra.util; public interface ICleverQueue extends IQueue { void remove(int n); int size(); }
Queue.java ... public class Queue implements IQueue { protected Vector v = new Vector(); public void put(Object o) { v.add(o); } ... } CleverQueue.java ... public class CleverQueue extends Queue implements ICleverQueue { ... }
Konstans az interfészben • Feladat – Számla • Kérjünk be egy forintösszeget, majd írjuk ki az értékét euróban! ... interface Euro { int ARFOLYAM = 230; String NEV = "EURO"; } public class Szamla implements Euro { public static void main (String args[]) { int ftOsszeg = Console.readInt("Összeg (Ft): "); System.out.println((ftOsszeg/ARFOLYAM)+" "+NEV); } }
Belső osztály • Osztályon belül deklarált másik osztály:class <KulsoOsztályAzon> ... { ... class <BelsoOsztályAzon> ... { ... }} • Csak az őt deklaráló külső osztály ismeri • Példányosítás: külső osztály példánymetódusából
Belső osztály (folyt.) • Példánya ismeri az őt létrehozó külső objektumot • implicit referencia • hivatkozás takarásnál: KülsőOsztály.this • Nem lehetnek statikus deklarációi • Nem kötelező azonosítani (névtelen belső osztály) • Fordítóprogram különálló külső osztállyá alakítja: KülsőOsztályAzon$BelsőOsztályAzon.classKülsőOsztályAzon$n.class (n=1,2,…)
Feladat – UdvarApp • Egy udvaron különböző négyzetes oszlopok vannak elhelyezve. Tartsuk nyilván az udvar és az oszlopok adatait, majd készítsünk róluk jelentést! Ne engedjünk olyan oszlopot létrehozni, amely az udvaron kívülre esik!
import java.util.*; class Udvar { // Udvar.class private int szel=100, hossz=50; private Vector oszlopok = new Vector(); public Udvar() { oszlopok.add(new Oszlop(25,30)); oszlopok.add(new Oszlop(40,5)); oszlopok.add(new Oszlop(97,10)); }
class Oszlop { // Udvar$Oszlop.class private int x, y; private int szel=5; public Oszlop(int x, int y) { if (x>=0 && x<=Udvar.this.szel-szel && y>=0 && y<=hossz-szel) { this.x = x; this.y = y; } else { this.x = 0; this.y = 0; } }