A Java minden új verziója eltér a korábbiaktól. Íme egy példa az általunk tárgyalt anyagok változásaira: a Java 5 előtt a nyelvnek nem volt
Hasonlóképpen, a Java 8 markánsan eltér a Java 7-től. A legtöbb leckét a nyelv 7. verziójára írtuk, de természetesen nem hagyjuk figyelmen kívül a fontos újításokat sem. Mivel ebben a leckében már interfészekről beszélünk, egy frissítést fogunk megfontolni – az alapértelmezett metódusokat az interfészekben . Már tudja, hogy egy felület nem valósítja meg a viselkedést . Feladata, hogy leírja azt a viselkedést, amellyel az azt megvalósító összes objektumnak rendelkeznie kell. A fejlesztők azonban gyakran találkoztak olyan helyzetekkel, amikor egy metódus megvalósítása minden osztályban azonos. Nézzük a régi autónk példáját:
enum
s. ![Alapértelmezett metódusok az interfészekben - 1](https://cdn.codegym.cc/images/article/34d25d0e-f8da-43f7-ab2b-5333c5a01585/800.jpeg)
public interface Car {
public void gas();
public void brake();
}
public class Sedan implements Car {
@Override
public void gas() {
System.out.println("Gas!");
}
@Override
public void brake() {
System.out.println("Brake!");
}
}
public class Truck implements Car {
@Override
public void gas() {
System.out.println("Gas!");
}
@Override
public void brake() {
System.out.println("Brake!");
}
}
public class F1Car implements Car {
@Override
public void gas() {
System.out.println("Gas!");
}
@Override
public void brake() {
System.out.println("Brake!");
}
}
"Szerinted mi a fő probléma ezzel a kóddal? Valószínűleg észrevetted, hogy egy csomó ismétlődő kódot írtunk! Ez a probléma gyakori a programozásban, és ezt el kell kerülni. Más kérdés, hogy bizonyos megoldások korábban nem léteztek Megjelent a Java 8. Ezzel a verzióval lehetővé vált az alapértelmezett metódusok megadása és azok közvetlenül a felületen belüli implementálása! Ezt a következőképpen teheti meg:
public interface Car {
public default void gas() {
System.out.println("Gas!");
}
public default void brake() {
System.out.println("Brake!");
}
}
public class Sedan implements Car {
}
public class Truck implements Car {
}
public class F1Car implements Car {
}
Most az gas()
és brake()
metódusok, amelyek minden autónál azonosak voltak, átkerültek a felületre. Nincs szükség ismételt kódra. Sőt, a módszerek minden osztályban elérhetőek!
public class Main {
public static void main(String[] args) {
F1Car f1Car = new F1Car();
Sedan sedan = new Sedan();
Truck truck = new Truck();
truck.gas();
sedan.gas();
f1Car.brake();
}
}
Mi van akkor, ha 100 osztály rendelkezik a gas()
metódussal, de közülük csak 99 viselkedése azonos? Ez mindent tönkretesz, és az alapértelmezett módszert alkalmatlanná teszi erre a helyzetre? Persze, hogy nem :) Az interfészekben az alapértelmezett metódusok ugyanúgy felülírhatók, mint a hétköznapiak.
public class UnusualCar implements Car {
@Override
public void gas() {
System.out.println("This car accelerates differently!");
}
@Override
public void brake() {
System.out.println("This car decelerates differently!");
}
}
Mind a 99 egyéb autótípus az alapértelmezett módszert alkalmazza, és aUnusualCar
osztály, ami kivétel, nem rontja el az összképet, és nyugodtan meghatározza saját viselkedését. Interfészek többszörös öröklődése. Mint már tudja, a Java nem támogatja a többszörös öröklődést. Ennek számos oka van. Egy külön leckében részletesen megvizsgáljuk őket. Más nyelvek, például a C++, támogatják. Többszörös öröklődés nélkül komoly probléma adódik: egy objektum többféle tulajdonsággal és „viselkedéssel” rendelkezhet. Íme, egy példa az életből: szüleink számára gyerekek vagyunk, tanáraink számára diákok, orvosaink számára betegek vagyunk. Az életben különböző szerepeket vállalunk, és ennek megfelelően eltérően is viselkedünk: nyilván nem beszélnénk úgy a tanárokkal, mint a közeli barátainkkal. Próbáljuk meg ezt kódra fordítani. Képzeljük el, hogy két osztályunk van: Tó és madárház. A tóhoz vízimadarak kellenek; a madárházhoz repülő madarakra van szükségünk. Ehhez két alaposztályt hoztunk létre:FlyingBird
és Waterfowl
.
public class Waterfowl {
}
public class FlyingBird {
}
Ennek megfelelően azokat a madarakat, amelyek osztályai örökölnek FlyingBird
, küldjük a madárházba, és az örökös madarakat Waterfowl
a tóba. Minden nagyon egyszerűnek tűnik. De hova küldjünk kacsát? Úszik és repül. És nincs többszörös örökségünk. Szerencsére a Java támogatja az interfészek többszörös megvalósítását. Bár egy osztály nem örökölhet több szülőt, könnyen megvalósíthat több felületet! A mi kacsánk lehet repülő madár és vízimadár is :) Egyszerűen nem osztályokat, hanem interfészeket kell készítenünk FlyingBird
a Waterfowl
kívánt eredmény eléréséhez.
public class Duck implements FlyingBird, Waterfowl {
// The methods of both interfaces can be easily combined into one class
@Override
public void fly() {
System.out.println("Fly!");
}
@Override
public void swim() {
System.out.println("Swim!");
}
}
Ennek megfelelően programunk megőrzi az osztályok rugalmasságát, és az alapértelmezett metódusokkal kombinálva szinte korlátlanná válik az objektumok viselkedésének definiálása! :)