Utolsó módosítás: 2016.10.26.
final módosítóAmenyiben nem szeretnénk, hogy egy változó értéke inicializálása után megváltozzon, elláthatjuk final módosítóval. Egy ilyen változó értékének felülírása fordítási hibát eredményez:
FinalErr.java:4: error: cannot assign a value to final variable n
n = 2;
^
vagy
FinalErr.java:6: error: variable n might already have been assigned
n = 1;
^
Egy módosíthatatlan változó esetén ügyelni kell, hogy csak egyszer, az inicializálás során adjunk értéket. Az n változó deklarációja és inicializációja (röviden definíciója) az alábbi:
final int n = 0;
Amennyiben egy osztály adattagja módosíthatatlan, akkor szintén oda kell figyelni az inicializációra. A változót inicializálhatjuk is rögtön a deklaráció helyén, vagy a konstruktorokban adunk neki értéket egyszer.
class A {
final int n = 0; // ok
}
class B {
final boolean b;
public B() {
b = true; // ok, első értékadás
b = false; // hibás
}
A final módosítónak az osztályok közötti öröklődéssel kapcsolatban is van jelentése. Erről az öröklődésnél lesz szó.
Az interfészek lehetővé teszik a szoftver tervezését anélkül, hogy a megvalósításra kelljen gondolnunk.
Egy interfész definíciója változók és metódusok deklarációjának és, a Java 8-as verziójával kezdve, metódusok definíciójának sorozata.
Az interfészen belüli változók alapértelmezés szerint public final static módosítókkal vannak ellátva, ezért ezeket kitenni felesleges. A metódus deklarációk és definíciók alapértelmezetten public láthatósággal rendelkeznek, így ezt sem kell kitenni.
public interface Car {
boolean b = true; // ok
int a = b; // hibás
int b = 2; // ok
int c = c * 3; // hibás
void accelerate(); // ok
}
Egy interfész egy új referencia típust vezet be. Létrehozhatunk egy változót, melynek típusa valamely interfész (például a fenti Car). Ekkor a változónak értékül adhatjuk bármely olyan objektum referenciáját, melynek osztálya megvalósítja az interfészt. Például, ha a fenti Car interfészt megvalósítja a Google önvezető járműve, akkor az alábbi kód helyes:
Car c = new GoogleCar();
Az interfészek kapcsolatban állhatnak egymással: ezt a kapcsolatot kiterjesztésnek nevezzük, melyet az extends kulcsszóval jelzünk. Eszerint az interfészek szülő-gyermek viszonyban állnak egymással. Egy interfész tehát a törzsében deklarált változókból és metódusokból, illetve az általa kiterjesztett interfészek váltózóiból és metódusaiból áll.
public interface SelfDrivingCar extends Car, GPS {
void driveToLocation(Position coordinates);
}
Egy osztály abban az esetben implementál egy interfészt, ha annak minden metódusához rendel törzset. Ehhez jelezni kell a szándékot az osztály definíciójának fejlécében az implements kulcsszót használva, és minden, az interfészben deklarált metódusnak nyilvánosnak kell lennie. Ellenkező esetben a fordító hibát jelez.
public class GoogleCar implements SelfDrivingCar {
public void accelerate() { /* ... */ }
public void driveToLocation(Position coordinates) { /* ... */ }
/* A GPS interfész műveletei */
}
Egy közismert interfész a java.lang.Comparable. Ezt megvalósítják azok az osztályok, melyek objektumai összehasonlíhatók: java.lang.Integer, java.lang.String, java.util.Date stb.
A java.lang.Comparable interfész egyetlen művelete a compareTo(), mely paraméterül vár egy másik objektumot. A compareTo() negatív egészt ad vissza, ha a this objektum kisebb, mint a paraméter, nullát, ha egyenlők, és pozitív egészt, ha a this nagyobb, mint a paraméter valamilyen reláció szerint.
public interface Comparable<T> {
int compareTo(T other);
}
Például:
Integer n = 2;
Integer m = 4;
n.compareTo(m); // -1
Készítsük el a publikus geometry.Movable interfészt! Ez deklarálja a move() metódust, mely paraméterül vár két int típusú távolságot (függőleges és vízszintes), és nincs visszatérési értéke.
Készítsük el a publikus geometry.Figure interfészt! Ez kiterjeszti a fenti Movable és a java.lang.Comparable<Figure> interfészt az alábbi metódusokkal:
Egy double visszatérési típusú area(), mely kiszámolja a síkidom területét.
Egy String visszatérési típusú show(), mely visszaadja a síkidom szöveges reprezentációját.
Valamint a Comparable interfész compareTo() metódusának adjunk egy alapértelmezett definíciót! Ez a síkidomokat területük alapján hasonlítja össze. Az a nagyobb síkidom, amelyiknek a területe nagyobb.
Készítsük el a publikus geometry.Circle osztályt, mely egy kört fog ábrázolni! Az osztály megvalósítja a Figure interfész műveleteit.
Deklaráljunk három privát int adattagot, melyek a kör közepének koordinátáit és a kör sugarát tárolják!
Készítsünk egy konstruktort, mely paraméterül várja a kör középpontjának x, y koordinátáit és a kör sugarát, és ezekkel inicializálja az adattagokat!
Készítsünk egy alapértelmezett konstruktort is, mely a kör középpontját az origóba és a kör sugarát 1-re állítja!
Valósítsuk meg a Figure interfész műveleteit! Ezek a következők: move(), area(), compareTo() és show().
A show() eredményére egy lehetséges példa: "Circle at (2,4) radius: 5"
Készítsük el a publikus geometry.Square osztályt, melynek egy objektuma egy négyzetet fog ábrázolni! Ez az osztály is megvalósítja a Figure interfész műveleteit.
Deklaráljunk három privát, int típusú adattagot, melyek a négyzet bal felső sarkának koordinátáit és a négyzet oldalának hosszát ábrázolják!
Definiáljunk egy konstruktort, mely paraméterül várja az adattagok kezdeti értékét, és ezekkel inicializálja az objektumot!
Definiáljunk egy alapértelmezett konstruktort, mely a bal felső sarkot az origóba, az oldal hosszát 1-re állítja.
Valósítsuk meg a Figure interfész műveleteit! Ezek a következők: move(), area() és show().
A show() eredményére egy lehetséges példa: "Square at (1,-2) side: 3"
Készítsük el a geometry csomagon kívül a FigureDemo osztályt! Definiáljuk az alábbi két metódust:
Egy statikus, Figure visszatérési típusú biggest metódust, mely paraméterül várja Figure referenciák listáját (elfogadunk ArrayList-et és LinkedList-et is, ezért várjunk paraméterül egy List referenciát)!
A metódus egy maximumkiválasztást valósít meg a síkidomokon, és visszaadja a listából a legnagyobb területű síkidom referenciáját. Két síkidom összehasonlításához használjuk a compareTo() metódust! Használjunk iterátort a paraméter lista bejárására! Iterátort a lista iterator() metódusával tudunk kérni.
Írjunk main() metódust a biggest() kipróbálására! Inicializáljunk egy List referenciát egy LinkedList objektummal és töltsük föl néhány síkidommal. Írassuk is ki a legnagyobb síkidom szöveges reprezentációját!