1. Minden osztály örökölObject
A Java minden osztálya implicit módon örökli az Object
osztályt.
A Java Core küldetésben elemezzük, mi az öröklődés, és hogyan működik a Java nyelven. Egyelőre egy egyszerű tényt veszünk figyelembe, amely ebből következik:
Bármely osztály objektuma hozzárendelhető egy Object
változóhoz. Példa:
Kód | jegyzet |
---|---|
|
A változó egy objektumra o való hivatkozást tárolScanner |
|
A változó egy objektumra o való hivatkozást tárolString |
|
A változó egy objektumra o való hivatkozást tárolInteger |
|
A változó egy objektumra o való hivatkozást tárolString |
Itt ér véget a jó hír. A fordító nem követi nyomon a változóban elmentett objektum eredeti típusát Object
, így nem lehet más metódusokat hívni a mentett objektumon, csak az osztály metódusait Object
.
Ha meg kell hívnia az objektum eredeti típusához tartozó metódusokat, akkor először el kell mentenie egy hivatkozást egy megfelelő típusú változóba, majd meghívnia kell a metódusokat azon a változón:
Kód | jegyzet |
---|---|
|
A program nem fog lefordítani. Az Object osztálynak nincs nextInt() metódusa. |
|
Ez működni fog. Itt elmentünk egy hivatkozást egy változóban Scanner lévő objektumra egy typecast operátorScanner segítségével . |
Nem lehet egyszerűen hozzárendelni egy Object
változót a Scanner-változóhoz, még akkor sem, ha a Object
változó hivatkozást tárol egy Scanner
objektumra. De ezt megteheti, ha a typecast operátort használja , amelyet már ismer. Ez az általános megjelenése:
Type name1 = (Type) name2;
Ahol name1
egy változó neve Type
, és name2
egy olyan változó neve Object
, amely egy objektumra való hivatkozást tárol Type
.
Typecasting
Ha a változó típusa és az objektum típusa nem egyezik, akkor a-t ClassCastException
dob ki. Példa:
Kód | jegyzet |
---|---|
|
Futás közben hiba fog fellépni: itt a ClassCastException lesz dobva |
Van egy módja annak, hogy elkerüljük ezt a hibát a Java-ban: ezt úgy tehetjük meg, hogy ellenőrizzük a változóban tárolt objektum típusát :
name instanceof Type
Az instanceof
operátor ellenőrzi, hogy a name
változó objektum-e Type
.
Példaként keressünk egy karakterláncot különböző objektumok tömbjében:
Kód | jegyzet |
---|---|
|
Integer Az Autoboxing ezeket az értékeket , String , és formátumba konvertálja Double . Hurok az objektumok tömbjén Ha az objektum egy String Mentés változóba A String változó megjelenítése a képernyőn. |
2. Miért jelentek meg a generikumok – gyűjtemények
Térjünk vissza a gyűjteményekhez.
Amint a Java fejlesztők létrehozták az ArrayList
osztályt, univerzálissá akarták tenni, hogy bármilyen típusú objektumot tárolhasson. Tehát egy s tömböt használtak Object
az elemek tárolására.
Ennek a megközelítésnek az az erőssége, hogy bármilyen típusú objektumot hozzáadhat a gyűjteményhez.
Természetesen több gyenge pont is van.
Hátrány 1.
A gyűjtemény elemeinek lekérésekor mindig meg kellett írni egy típuskonverziós operátort:
Kód | jegyzet |
---|---|
|
Object Gyűjtemény létrehozása az objektumokra való hivatkozások tárolására Töltse ki a gyűjteményt számokkal 10 , 20 , ... 100 ; Összegezzük a gyűjtemény elemeit Typecasting szükséges |
Hátrány 2.
Nem volt garancia arra, hogy egy gyűjtemény meghatározott típusú elemet tartalmaz
Kód | jegyzet |
---|---|
|
Object Gyűjtemény létrehozása az objektumokra való hivatkozások tárolására A gyűjteményt objektumként ábrázolt számokkal töltjük fel Double : 0.0 , 2.5 , 5.0 , ... A gyűjtemény elemeinek összegzése Hiba lesz: a Double nem küldhető át egyInteger |
Az adatok bárhol behelyezhetők a gyűjteménybe:
- más módszerrel
- egy másik programban
- fájlból
- hálózaton keresztül
Hátrány 3.
A gyűjteményben lévő adatok véletlenül megváltozhatnak.
Az adataival feltöltött gyűjteményt átadhatja valamilyen módszernek. Ez a módszer, amelyet egy másik programozó írt, hozzáadja az adatait a gyűjteményéhez.
A gyűjtemény neve nem jelzi egyértelműen, hogy milyen típusú adatok tárolhatók benne. És még ha egyértelmű nevet ad is a változónak, a rá való hivatkozás átadható egy tucat metódusnak, és ezek a metódusok biztosan nem fognak tudni semmit a változó eredeti nevéről.
3. Általános szerek
A Java-ban mindezeket a problémákat kiküszöböli ez a klassz dolog, az úgynevezett generikus.
A Java nyelvben az általános kifejezés azt jelenti, hogy típusparamétereket adhatunk a típusokhoz. Az eredmény egy összetett összetett típus. Az ilyen összetett típus általános nézete a következő:
ClassName<TypeParameter>
Ez egy általános osztály. És bárhol használható, ahol általában osztályokat használ.
Kód | Leírás |
---|---|
|
Változók létrehozása |
|
Objektumok létrehozása |
|
Tömbök létrehozása |
Egy ilyen gyűjteményben csak Integer
változók tárolhatók:
Kód | Leírás |
---|---|
|
ArrayList gyűjtemény Integer elemekkel Ez megengedett És ez is működni fog
Autobox
De ez nem megengedett: fordítási hiba |
Megtanulja, hogyan hozhat létre saját osztályokat típusparaméterekkel a Java Collections küldetésben. Egyelőre megnézzük, hogyan kell használni és hogyan működnek.
4. Hogyan működnek a generikumok
Valójában a generikumok borzasztóan primitívek.
A fordító egyszerűen lecseréli az általános típusokat közönséges típusokra. Ám ha általános típusú metódusokat használnak, a fordító egy typecast operátort ad hozzá, hogy a típusparaméterekhez öntsön paramétereket:
Kód | Mit csinál a fordító |
---|---|
|
|
|
|
|
|
|
|
Tegyük fel, hogy van egy metódusunk, amely az egész számok gyűjteményében lévő számokat összegzi:
Kód | Mit csinál a fordító |
---|---|
|
|
Más szóval, a generikumok egyfajta szintaktikai cukor, mint az autoboxing, de egy kicsit több. Az autoboxing esetén a fordító metódusokat ad hozzá az an- int
ra Integer
és fordítva, az általánosoknál pedig typecast operátorokat ad hozzá.
Miután a fordító összeállította az általános osztályokat a típusparaméterekkel, egyszerűen átalakítja őket közönséges osztályokká és typecast operátorokká. Az általános típusú változóknak átadott típusargumentumokkal kapcsolatos információk elvesznek. Ezt a hatást típustörlésnek is nevezik .
Néha az általános osztályokat (típusparaméterekkel rendelkező osztályokat) író programozóknak valóban szükségük van az argumentumként átadott típusokra vonatkozó információkra. A Java Collections küldetés során megtudhatja, hogyan kezelje ezt, és mit jelent ez.
5. Néhány tény a generikus gyógyszerekről
Íme néhány érdekes tény a generikus gyógyszerekről.
Az osztályoknak többféle típusparamétere lehet. Valahogy így néz ki:
ClassName<TypeParameter1, TypeParameter2, TypeParameter3>
Valójában ez nem is meglepő. Bárhol, ahol a fordító hozzá tud adni egy operátort egy típushoz, több typecast operátort is hozzáadhat.
Példák:
Kód | jegyzet |
---|---|
|
A put metódus első paramétere an Integer , a második pedig aString |
Általános típusok is használhatók paraméterként . Valahogy így néz ki:
ClassName<TypeParameter<TypeParameterParameter>>
Tegyük fel, hogy szeretnénk létrehozni egy listát, amely karakterláncok listáját tárolja. Ebben az esetben valami ilyesmit kapunk:
// List of greetings
ArrayList<String> listHello = new ArrayList<String>();
listHello.add ("Hello");
listHello.add ("Hi");
// List of goodbyes
ArrayList<String> listBye = new ArrayList<String>();
listBye.add("Bye");
listBye.add ("Goodbye");
// List of lists
ArrayList<ArrayList<String>> lists = new ArrayList<ArrayList<String>>();
lists.add(listHello);
lists.add(listBye);
Az általános típusok (típusparaméterekkel rendelkező típusok) tömbtípusként is használhatók. Valahogy így néz ki:
ClassName<TypeParameter>[] array = new ClassName<TypeParameter>[size];
Itt nem történik semmi varázslatos: a szögletes zárójelek csak a típus nevét jelzik:
Kód | Nem általános megfelelője |
---|---|
|
|
|
|
|
|
GO TO FULL VERSION