2010.12.11. 18:45
Declare Classes [Declarations and Access Control]
A második alfejezet vizsgához szükséges célja:
1.1 Fejlesszünk olyan kódot, ami osztályokat (beleértve az absztrakt és a beágyazott osztályok minden típusát), interfészeket és enumokat deklarál és használja a szükséges package és import parancsokat (beleértve a static importot is).
A Javaban való programozás során gyakorlatilag osztályokat és interfészeket hozunk létre. Ezek deklarálása jelentősen befolyásolja a program működését, felépítését. Néhány alapvető szabály:
- Egy forrás fájl csak egy publikus osztály deklarációt tartalmazhat.
- Kommentek bárhol előfordulhatnak a forrásban, kezdődhetnek sor közben, vagy sor elején is.
- Ha egy fájl tartalmaz egy publikus osztály deklarációt, akkor a fájl nevének meg kell egyeznie ezen osztály nevével (pl.: public class Dog { } a Dog.java forrásfájlban kell legyen).
- Ha az osztály egy csomag része, akkor a package parancsnak a forrás első sorában kell lennie, az esetleges importok előtt.
- Ha használunk import parancsokat, akkor azoknak a package definíció után és az osztály deklaráció előtt kell lenniük. Ha nincs sem package, sem import definíció, akkor az osztály deklarációval kezdődik a forrás fájl.
- Egy fájlon belüli package és import parancsok minden osztályra vonatkoznak, amelyek ezen fájlban vannak deklarálva. Más szóval nem lehetséges azonos forráson belül két különböző packagebe tartozó osztályt definiálni, hasonlóan nem lehet őket különböző import parancsokkal ellátni.
- Egy forráson belül több nem-publikus osztályt is lehet deklarálni.
- Az olyan forrás fájlnak, mely csak nem-publikus osztály deklarációkat tartalmaz eltérhet a neve minden osztály elnevezésétől.
Osztály deklaráció és módosítók
A legegyszerűbb osztály deklaráció, amely le is fordul:
class MyClass { }
Az osztályt, hasonlóan a metódusokhoz és osztályváltozókhoz, módosítókkal - modifierekkel láthatunk el. Ezeket két csoportra oszthatjuk:
- Access modifiers:
public, protected, private
- Non-access modifiers (osztályok esetén):
strictfp, final, abstract
Az access modifier-ek gyakorlatilag kulcsszavak, amik szabályozzák a láthatóságot, meghatározzák az access controlt. A dolog érdekessége, hogy míg 4 access control van, addig hozzá csak az említett 3 access modifier van. A negyedik control ugyanis a default, vagy package - csomag szintű access. Ha ezt szeretnénk használni, akkor egyszerűen nem írunk access modifiert. Alapértelmezetten tehát minden osztály package szintű accessel rendelkezik, de használva a három modifier egyikét, ez megváltoztatható. Egészen pontosan osztályok esetén csak a public használható, mert - mint majd egy későbbi fejezetben látni fogjuk - a protectednek és a private-nak nincs értelme. Marad tehát a default és a public.
Megjegyzés: A Java csomag centrikus nyelv, ami azért hasznos, mert így a különböző cégek, különböző programjainak és azok különböző részeinek osztályai egyértelműen elkülöníthetőek, normális esetben nem fordulhat elő névütközés. Az általános szabály a csomagok elnevezésére a fordított domain név, majd a project neve, végül ha szükséges, annak részegysége. Így például: com.company.project.client. Adott csomag részegysége fájl szinten könyvtárat jelöl, a csomagon belüli osztályok forrása pedig az abban lévő fájlokat.
Osztály access
Mit is jelent az, hogy A osztály hozzáfér B osztályhoz (másnéven B látható A számára)? Azt jelenti, hogy A a következő három dolgot teheti meg:
- Létre tud hozni egy példányt B-ből.
- Ki tudja terjeszteni B-t, azaz gyermek osztálya tud lenni.
- Hozzáfér B metódusaihoz és változóihoz, attól függően, hogy azok milyen access controllal rendelkeznek.
Gyakrolatilag tehát B access controllja meghatározza az ő láthatóságát más osztályok felé. Amennyiben más osztály nem látja B-t, úgy B metódusainak és változóinak saját access controllja már nem is számít.
Default access
Ha egy osztály deklarációját nem látunk el modifierrel, úgy default, vagy package accesst fog kapni. Erre úgy kell gondolni, hogy csak a vele azonos osztályban lévő osztályok számára lesz látható. Egy példa:
package cert;
class Beverage { }
Másik forrás:
package exam.stuff;
import cert.Beverage;
class Tea extends Beverage { }
Az első fájl sikeresen lefordul, a második azonban nem, mert számára nem látható osztályt próbál importálni és azt kiterjeszteni. Ilyesmi hibaüzenetet kapunk:
Can't access class cert.Beverage. Class or interface must be public, in same package, or an accessible member class.
import cert.Beverage;
A megoldás az lehet, hogy azonos csomagba helyezzük őket, vagy a Beverage osztályt public-ként deklaráljuk. A vizsgán érdemes figyelni a láthatóságot, mert előfordul, hogy egy kérdésnél meg sem kell vizsgálni a feladatban szereplő kód logikáját, hanem rögtön azt a választ adhatjuk, hogy a kód nem fordul.
Public access
Ha egy osztályt ellátjuk a public kulcsszóval, akkor minden java osztály számára láthatóvá válik. Persze ha más csomagból szeretnénk használni, akkor nem szabad megfeledkezni az importálásáról. Az előző példa megoldása tehát:
package cert;
public class Beverage { }
Más (nem hozzáférést szabályozó) osztály módosítók
Módosíthatjuk az osztály deklarációt a strictfp, abstract, vagy final kulcsszóval is. Ezeket az access modifierektől függetlenül és egymás mellett is használhatjuk. Természetesen nem ilyen egyszerű, mert itt is van kivétel: nem használhatjuk együtt a final és az abstract kulcsszót.
A strictfp kulcsszó ismerete nem szükséges a viszgához, elég róla annyit tudni, hogy használhatjuk metódusok definíciója előtt is, és osztályok esetén is. Ez utóbbi esetben azt határozzuk meg, hogy az osztály minden metódusa megfelel az IEEE 754 szabvány lebegőpontos számok szabályainak. Különben eltérő platformokon ezek eltérőek lehetnek.
Final osztályok
Ha a final kulcsszót használjuk, akkor azzal azt deklaráljuk, hogy az osztály nem kiterjeszthető, azaz véglegesítjük. A gyakorlatban ezt ritkán kell megtennünk (hiszen az objektum orientált programozás alapvető tulajdonságának, a kiterjeszthetőségnek mond ellent), általában csak akkor, ha biztosra akarunk menni, hogy más programozó véletlenül sem módosít osztályunk működésén és nem készít alternatív gyermek osztályt. Leginkább a Java alaposztályok, mint a String vannak final-ként deklarálva, hogy megóvjanak az ilyen elemi osztályok kiterjesztéséből adódó hibáktól. Ne feledjük, hogy ha egy osztályt final-ként deklarálunk, akkor az esetleges hibákat forráskód nélkül már más nem tudja javítani.
Az előző példát folytatva:
package cert;
public final class Beverage {
public void importantMethod() { }
}
Ha megpróbáljuk lefordítani a Tea osztályt:
package exam.struff;
import cert.Beverage;
class Tea extends Beverage { }
Akkor a következő fordítási hibát kapjuk:
Can't subclass final classes: class cert.Beverage
class Tea extends Beverage {
1 error
Absztrakt osztályok
Az absztrakt osztály nem példányosítható, csak kiterjeszthető. Ilyen módon nagyjából az ellentéte a finalnek. Érdemes olyan osztályokat abstractként deklarálni, amelyek vannak annyira általánosak, hogy noha tartalmazhatnak nem absztrakt eljárásokat, de várhatóan specializált gyermek osztályok készülnek hozzá. Például egy Car osztály túl összetett lenne, ha minden típus speciális tulajdonságát tárolni akarnánk, ehelyett gyermek osztályokat készítünk.
abstract class Car {
private double price;
private String model;
private String year;
public abstract void goFast();
public abstract void goUpHill();
public abstract void impressNeighbors();
}
Az absztrakt osztály fordítható és futtatható, mindaddig, amíg nem akarjuk példányosítani. Ebben az esetben ilyen hibaüzenetet kapunk:
AnotherClass.java:7: class Car is an abstract class. It can't be instantiated.
Car x = new Car();
1 error
Figyeljünk arra, hogy az abstract kulcsszóval ellátott eljárások nem kapcsos zárójellel végződnek, hanem pontosvesszővel. Ez deklarálja a metódust, de a konkrét definíciót a gyermek osztálynak kell elvégeznie - amennyiben az nem absztrakt. Ha egy osztály legalább egy absztrakt metódust tartalmaz, akkor az osztályt is abstractként kell megjelölnünk. Ellenben az absztrakt osztály tartalmazhat nem absztrakt függvényeket is. Ezeket minden gyermek osztály örökölni fogja, azokban elegendő lesz az absztrakt illetve az opcionális egyéb metódust definiálni.
Jelentésében tehát annyira eltér az abstract és final, hogy azokat párban használva fordítási hibát kapunk.
2010.12.05. 20:25
Identifiers & JavaBeans [Declarations and Access Control]
Az első fejezet címe Declarations and Access Control, ahogy a bejegyzés címéből is látszik. A fő fejezetcímeket az aktuális alfejezet címe mögött így fogom jelölni. Minden alfejezetnek van néhány Certification Objective-je, melyek elérendő célok a vizsgára. Egy alfejezet nem feltétlen fedi a felsorolt objective-okat, sokszor inkább szükséges építőeleme annak. Következzen tehát az első alfejezet, melynek a vizsgához szükséges céljai:
1.3 Fejlesszünk olyan kódot, ami deklarál, inicializál és használ primitíveket, tömböket, enumokat és objektumokat mint statikus, osztály-szintű és lokális változókat. Használjunk legális változóneveket.
1.4 Fejlesszünk olyan kódot, ami deklarál statikus és nem statikus eljárásokat és - ha lehetséges - használjuk a JavaBeans elnevezési szabványát. Továbbá fejlesszünk olyan kódot, ami deklarál és használ egy változó hosszúságú argumentum listát.
A Java azonosítókat három szempont szerint csoportosíthatjuk:
- Legális azonosítók: Azon szabályok összessége, amelyek meghatározzák a fordító számára, hogy mely elnevezések legálisak.
- A Sun Java Code Conventions: Általánosan elfogadott elnevezési konvenció, melyet érdemes követni, hiszen a legtöbb programozó kisebb eltérésekkel, de ezt használja. A vizsgának nem része, de erősen ajánlott, hogy ismerjük.
- JavaBeans Naming Standards: A JavaBeans specifikáció elnevezésbeli követelményei. A JavaBeans specifikáció szintén nem része a vizsgaanyagnak, de néhány alapvető elnevezésekre vonatkozó szabályt ismerni kell.
Legális azonosítók
A legális azonosítók unicode karakterekből, számokból, pénzügyi szimbólumokból és összekötő karakterekből (pl.: _) épülnek fel. A vizsga letételéhez nem kell ismerni pontosan az unicode megengedett tartományait, de amit tudni kell, azok a következők:
Az azonosítóknak betűvel, pénzügyi szimbólummal, vagy összekötő karakterrel kell kezdődniük. Szám nem lehet az első karakter.
A második karaktertől bármilyen kombinációját tartalmazhatja a betűknek, pénzügyi szimbólumoknak, összekötő karaktereknek, számoknak.
Gyakorlatilag nincs korlátozva az azonosítók hosszának.
Java kulcsszó nem használható azonosítónak. Alább a táblázat tartalmazza a Java kulcsszavakat.
Az azonosítónevek érzékenyek a kis és nagy betűkre, azaz foo és FOO két különböző azonosító.
abstract | boolean | break | byte | case | catch |
char | class | const | continue | default | do |
double | else | extends | final | finally | float |
for | goto | if | implements | import | instanceof |
int | interface | long | native | new | package |
private | protected | public | return | short | static |
strictfp | super | switch | synchronized | this | throw |
throws | transient | try | void | volatile | while |
assert | enum |
Sun Java Code Conventions
A Sun által javasolt kódolási konvenciók a "Java Code Conventions" nevű dokumentumban találhatóak meg. Általánosan elfogadott és a vizsgához is javasolt az ismerete, noha számítani kell rá, hogy a vizsgakérdésekben előforduló kódrészletek némileg eltérnek majd ettől. Ennek oka, hogy könnyebben feldolgozható és ellenőrizhető legyen géppel. A szabályok, amelyeket ismerni kell:
Osztály és interfész: Nagybetűvel kezdünk, és ha több szóból áll a név, akkor minden szó első karakterét naggyal írjuk, szóköz nélkül. Ezt az írásmódot camelCase-nek szokás nevezni. Osztálynevek általában főnevek (pl.: Dog, Account, PrintWriter), míg az interfészek általában melléknevek (pl.: Runnable, Serializable).
Eljárás: Kisbetűvel kezdünk, majd normál camelCase-el folytatjuk. Általában ige-főnév párokból épülnek fel (pl.: getBalance, doCalculation, setCustomerName).
Változó: Hasonlóan az eljárásokhoz, a camelCase szabványt ajánlatos használni kis kezdőbetűvel. Érdemes rövid, beszédes neveket alkalmazni (pl.: buttonWidth, accountBalance, myString).
Konstans: A Java konstansok static és final kulcsszóval ellátott változók, melyeket csupa nagybetűvel nevezünk el. A szavakat aláhúzás (_) karakterrel választjuk el (pl.: MIN_HEIGHT).
JavaBeans Standards
A JavaBeans specifikáció azért készült, hogy segítse a fejlesztőket, hogy szabványos Java komponenseket (un. bean) készítsenek, melyeket újra tudnak hasznosítani különböző IDE-kben. Így nem kell minden általános komponenst újra lefejleszteni, meg is lehet azokat vásárolni. A vizsgára elég néhány dolgot tudni a JavaBean-ekről.
Először is, a JavaBeanek Java osztályok, amelyek property-kkel rendelkezdnek. Ezekre úgy kell gondolni, mint privát változókra, melyek értékét csak publikus metódusokkal lehet lekérni és módosítani. Ezeket getter, illetve setter metódusoknak nevezzük.
JavaBean Property elnevezési szabályok:
- Ha a property nem boolean típusú, akkor a getter metódusnak a get szóval kell kezdődnie, melyet a property neve követ (pl.: getSize()). Ez utóbbi nem kötelező, nem feltétlenül kell, hogy létezzen olyan változó, mely a getter nevében szerepel, valamint az sem garantált, hogy a függvény tisztán a változó értékét adja vissza, lehet, hogy változtatásokat végez előbb azon.
- Ha a property boolean típusú, akkor get, vagy is a javasolt prefix (pl.: getStopped(), isStopped()).
- A setter metódus set prefix-el van ellátva (pl.: setSize()).
- A getter és setter metódusok get, set, illetve is prefixe után az érintett változó nevét úgy használjuk fel, hogy annak első betűjét nagyra cseréljük.
- A setter metódust publikusként kell megjelölni void visszatérési értékkel és egy argumentummal a property típusával.
- A getter metódust publikusként kell megjelölni, argumentum nélkül. A visszatérési érték a property típusával egyezik meg.
Másodszor a JavaBeans támogatja az eventeket, melyek arra alkalmasak, hogy értesítsenek más objektumokat bizonyos események, például egér kattintás bekövetkeztéről. Az objektumok, melyek fogadják az ilyen információkat, listenereknek nevezzük. A vizsgához tudni kell, hogy a metódusoknak, - melyek hozzáadnak, illetve eltávolítanak listenereket - szintén követniük kell némi JavaBeans elnevezésbeli szabványt:
- A listener metódus neveknek, melyek regisztrálnak egy listenert egy event source-hoz, az add kulcsszóval kell, hogy kezdődjenek, melyet a listener típusának neve követ. Például az addActionListener() egy érvényes metódusnév, mellyel az Action eventre lehet felíratkozni.
- Azon listener metódusok, melyek eltávolítanak egy listenert egy event source-ról, a remove kulcsszóval kell kezdődjenek, folytatva a listener típusának nevével. A szabályok megegyeznek az add-al.
- A listener típusát argumentumként kell feltüntetni az add, illetve remove függvényekben.
- A listener függvények neveinek a Listener szóval kell végződniük.
Példák érvényes JavaBeans elnevezésekre:
public void setMyValue(int v)
public int getMyValue()
public boolean isMyStatus()
public void addMyListener(MyListener m)
public void removeMyListener(MyListener m)
Példák érvénytelen JavaBeans elnevezésekre:
void setCustomerName(String s) //hiányzik a public
public void modifyMyValue(int v) //helytelen a modify szó
public void addXListener(MyListener m) //nem egyezik a listener típus
Fontos:
Az objective szerint csak a változónevekhez kell ismerni a legális elnevezéseket, de fontos tudni, hogy ugyanazon szabályok érvényesek minden Java komponensre. Azaz egy név ha legális mint változónév, akkor legális mint osztály, vagy metódus név is. Ugyanakkor fontos, hogy meg tudjuk különböztetni a legális elnevezéseket az elnevezésbeli szabványoktól. Tehát fel kell ismerni, hogy egy azonosító lehet legális, még ha nem is felel meg például a JavaBeans szabványnak. Ha a vizsgán külön a naming convention felől érdeklődnek (nem csak arról, hogy mi fordul le), akkor az alatt mindig a JavaBeans szabványt kell érteni.
2010.11.13. 07:56
Blog Kickoff
Azért született ez a blog, hogy segítse a felkészülést a Sun Certified Java Programmer vizsgára, mely a Sun egyik legáltalánosabban elfogadott Java vizsgája.
Terveim szerint a postokat saját tanulási fázisaimban fogom írni. Jómagam a felkészüléshez Kathy Sierra és Bert Bates Sun Certified Programmer for Java 6 (Exam 310-065) könyvét használom. A könyv beszerzését egyébként erősen ajánlom, mégha angol nyelvű is, mert a kb. 800 oldalban minden szükséges tudnivalóra felkészít, ráadásul a szerzői részt vettek a vizsga megalkotásában. A könyv mérete elrettentő lehet, de szerencsére emészthető, sok helyen humoros példákkal.
A postok írásánál a könyv struktúrája szerint fogok haladni az anyagon összefoglaló jelleggel, a részemről fontosnak ítélt területeket kiemelve. Nem célja a blognak, hogy magyar fordítást adjon a könyvnek, pusztán segít számomra is, hogy egy fejezet elolvasása után az összefoglalással jobban rögzüljenek bennem a tanultak, illetve később átolvasva a bejegyzéseket könnyen átismételhető legyen tetszőleges témakör. Remélem az olvasókat is segíteni fogja ez utóbbiban, sőt talán a vizsga letételéhez is elegendő lesz - meglátjuk.
Szeretném ha az olvasók kommentjeikkel tudatnák, ha egy-egy bejegyzés hasznos volt számukra, az ilyen visszajelzések motiválnak és elősegítik, hogy a blog életben is maradjon. Aki hibát talál, vagy plusz kiegészítést, az is mindenképpen szóljon hozzá, hiszen mindannyiunk javára válik, ha a bejegyzés melletti kommentekből részletesebben is tájékozódhatunk az adott témáról.
Ha a könyv végére érek, akkor példavizsgák, kérdéssorok, hasznos oldalak gyűjtésével, esetleg a Sun további Java vizsgáira való felkészítéssel fogom segíteni a vizsgázni vágyókat.
Készüljetek, hamarosan jön az első, igazi bejegyzés!