1. Képességek
Ahhoz, hogy jobban megértsük az interfészek előnyeit és használatukat, néhány elvontabb dologról kell beszélnünk.
Egy osztály általában egy adott objektumot modellez. Egy interfész kevésbé felel meg az objektumoknak, sokkal inkább a képességeiknek vagy szerepeiknek.

Például az autók, kerékpárok, motorkerékpárok és kerekek a legjobban osztályokként és tárgyakként ábrázolhatók. De a képességeiket – mint például a „lovagolhatok”, „tudok embereket szállítani”, „meg tudok állni” – jobban bemutatják interfészként. Íme néhány példa:
Kód | Leírás |
---|---|
|
Megfelel a mozgásképességnek |
|
Megfelel a lovaglási képességnek |
|
Megfelel a cuccok szállításának képességének |
|
Az Wheel osztály mozoghat |
|
Az Car osztály mozoghat , lovagolhat és szállíthat dolgokat |
|
Az Skateboard osztály mozoghat és lovagolható |
2. Szerepek
Az interfészek nagyban leegyszerűsítik a programozó életét. Nagyon gyakran egy program több ezer objektumot, több száz osztályt, de csak pár tucat interfészt , azaz szerepkört tartalmaz . Kevés a szerepkör, de sokféleképpen kombinálhatóak (osztályok).
A lényeg az, hogy nem kell minden osztályhoz kódot írnod ahhoz, hogy minden más osztállyal kommunikálj. Csak kölcsönhatásba kell lépnie a szerepeikkel (interfészekkel).
Képzeld el, hogy kisállat-oktató vagy. Mindegyik háziállat, akivel dolgozik, többféle képességgel rendelkezhet. Baráti vitába keveredik szomszédjával arról, hogy kinek a házi kedvence tud a legtöbb zajt kiütni. A dolog rendezéséhez csak sorba állítod az összes "beszélni" tudó háziállatot, és kiadod nekik a parancsot: Beszélj!
Nem érdekel, hogy milyen állatról van szó, vagy milyen egyéb képességekkel rendelkeznek. Még akkor is, ha képesek tripla hátszaltót csinálni. Ebben a pillanatban csak az érdekli, hogy képesek-e hangosan beszélni. Így nézne ki kódban:
Kód | Leírás |
---|---|
|
A CanSpeak képesség. Ez az interfész megérti a parancsot speak , ami azt jelenti, hogy rendelkezik egy megfelelő metódussal. |
|
Azok az állatok, amelyek rendelkeznek ezzel a funkcióval.
A könnyebb érthetőség érdekében az osztályok nevét angolul adtuk meg. Ez engedélyezett a Java-ban, de nagyon nem kívánatos.
|
|
És hogyan adjuk ki nekik a parancsot? |
Amikor a programjaiban az órák száma eléri az ezret, nem fog tudni élni felületek nélkül. Több ezer osztály interakciójának leírása helyett elég néhány tucat interfész interakcióját leírni – ez nagyban leegyszerűsíti az életet.
A polimorfizmussal kombinálva ez a megközelítés általában átütő sikert arat.
3. default
Interfész módszerek megvalósítása
Az absztrakt osztályoknak lehetnek változói és metódusmegvalósításai, de nem lehetnek többszörös öröklődésük. Az interfészek nem tartalmazhatnak változókat vagy metódusmegvalósításokat, de többszörösen öröklődnek.
A helyzetet a következő táblázat mutatja be:
Képesség/tulajdonság | Absztrakt osztályok | Interfészek |
---|---|---|
Változók | ✔ | ✖ |
A módszer megvalósítása | ✔ | ✖ |
Többszörös öröklés | ✖ | ✔ |
Tehát néhány programozó valóban azt akarta, hogy az interfészek képesek legyenek metódusmegvalósításra. De a metódusmegvalósítás hozzáadásának képessége nem jelenti azt, hogy egy mindig hozzáadásra kerül. Adja hozzá, ha akarja. Vagy ha nem, akkor ne.
Ezen túlmenően a többszörös örökléssel kapcsolatos problémák elsősorban a változókból adódnak. Mindenesetre így döntöttek és meg is tették. A JDK 8-tól kezdve a Java bevezette a metódusmegvalósítások interfészekhez való hozzáadásának lehetőségét.
Íme egy frissített táblázat (JDK 8 és újabb verziókhoz):
Képesség/tulajdonság | Absztrakt osztályok | Interfészek |
---|---|---|
Változók | ✔ | ✖ |
A módszer megvalósítása | ✔ | ✔ |
Többszörös öröklés | ✖ | ✔ |
Mostantól az absztrakt osztályok és interfészek esetében deklarálhat metódusokat implementációval vagy anélkül. És ez kiváló hír!
Az absztrakt osztályokban az implementáció nélküli metódusokat a abstract
kulcsszónak kell megelőznie. Nem kell semmit hozzáfűznie a megvalósítással rendelkező metódusok előtt. Az interfészek esetében ennek az ellenkezője igaz. Ha egy metódusnak nincs implementációja, akkor semmit sem kell hozzáadni. De ha van implementáció, akkor default
hozzá kell adni a kulcsszót.
Az egyszerűség kedvéért ezeket az információkat a következő kis táblázatban mutatjuk be:
Képesség/tulajdonság | Absztrakt osztályok | Interfészek |
---|---|---|
Megvalósítás nélküli módszerek | abstract |
– |
Módszerek megvalósítással | – | default |
Probléma
A metódusokkal rendelkező interfészek használata nagymértékben leegyszerűsítheti a nagy osztályhierarchiákat. Például az absztrakt InputStream
és OutputStream
az osztályok deklarálhatók interfészként! Így sokkal gyakrabban és kényelmesebben használhatjuk őket.
De már több tízmillió (milliárd?) Java osztály létezik a világon. És ha elkezdi megváltoztatni a szabványos könyvtárakat, akkor eltörhet valamit. Mint minden! 😛
Annak érdekében, hogy véletlenül se törjenek szét a meglévő programok és könyvtárak, úgy döntöttek, hogy az interfészek metódus-megvalósításainak lesz a legalacsonyabb öröklődési prioritása .
Például, ha az egyik interfész egy másik interfészt örököl, amelynek van metódusa, és az első interfész ugyanazt a metódust deklarálja, de implementáció nélkül, akkor az örökölt interfész metódus-megvalósítása nem éri el az öröklődő interfészt. Példa:
interface Pet
{
default void meow()
{
System.out.println("Meow");
}
}
interface Cat extends Pet
{
void meow(); // Here we override the default implementation by omitting an implementation
}
class Tom implements Cat
{
}
A kód nem fordul le, mert az Tom
osztály nem valósítja meg a meow()
metódust.
GO TO FULL VERSION