Java SE 8 API dokumentációja

Utolsó módosítás: 2016.10.26.

A 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ó.

Interfészek

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

Feladatok

  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.

  2. 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:

    1. Egy double visszatérési típusú area(), mely kiszámolja a síkidom területét.

    2. Egy String visszatérési típusú show(), mely visszaadja a síkidom szöveges reprezentációját.

    3. 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.

  3. 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.

    1. 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!

    2. 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!

    3. 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!

    4. 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"

  4. 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.

    1. 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!

    2. Definiáljunk egy konstruktort, mely paraméterül várja az adattagok kezdeti értékét, és ezekkel inicializálja az objektumot!

    3. Definiáljunk egy alapértelmezett konstruktort, mely a bal felső sarkot az origóba, az oldal hosszát 1-re állítja.

    4. 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"

  5. Készítsük el a geometry csomagon kívül a FigureDemo osztályt! Definiáljuk az alábbi két metódust:

    1. 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.

    2. Í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!