Aki követi a Java fejlődését, találhat egy érdekességet a JDK8 (Lambda build) kipróbálható verziójában, amely letölthető a http://jdk8.java.net/lambda/ oldalról: az interfészekben meg tudunk adni alapértelmezett kódrészletet, amely felüldefiniálható a leszármazott osztályban. A megoldás előnye, hogy ezzel lehetőségünk van egy interfészhez hozzáadni egy új metódust, s bevezetéséhez nem kell az összes leszármazottban ezt az új metódust implementálnunk.
Az interfész
Nézzünk egy példát, hozzunk létre egy interfészt, amelynek legyen egy meglévő metódusa, illetve egy új metódust, amelyet nem szeretnénk a leszármazott osztályokban implementálni:
interface LambdaInterface { public void oldMethod(); public void newMethod() default { System.out.println("Default behaviour"); } }
A megfelelő JDK8 használatával könnyedén lefordíthatjuk:
$ /opt/jdk1.8.0/bin/java -version openjdk version "1.8.0-ea" OpenJDK Runtime Environment (build 1.8.0-ea-lambda-nightly-h161-20120511-b39-b00) OpenJDK 64-Bit Server VM (build 24.0-b07, mixed mode) $ /opt/jdk1.8.0/bin/javac LambdaInterface.java
Az üres implementáció
Készítsünk egy implementációt, amely nem implementál egy metódust sem:
public class LambdaImplementation implements LambdaInterface { }
Fordításkor nyilván panaszkodni fog a fordító, hogy nem implementáltuk az oldMethod metódust:
$ /opt/jdk1.8.0/bin/javac LambdaImplementation.java LambdaImplementation.java:1: error: LambdaImplementation is not abstract and does not override abstract method oldMethod() in LambdaInterface public class LambdaImplementation implements LambdaInterface ^ 1 error
Implementáció egy metódussal
Implementáljuk a hiányolt metódust:
public class LambdaImplementation implements LambdaInterface { public void oldMethod() { System.out.println("Implemented oldMethod"); } }
Majd fordítsuk le, amely során azt kell tapasztalnunk, hogy hiba nélkül fordul:
$ /opt/jdk1.8.0/bin/javac LambdaImplementation.java $
Írjunk gyorsan futtató osztályt, amely egyszerűen példányosítja az implementációt, majd meghívja az interfész két metódusát:
public class LambdaRun { public static void main(String[] args) { LambdaInterface li = new LambdaImplementation(); li.oldMethod(); li.newMethod(); } }
A fordítás után, illetve futtatás során az alábbit kell lássuk:
$ /opt/jdk1.8.0/bin/javac LambdaRun.java $ /opt/jdk1.8.0/bin/java LambdaRun Implemented oldMethod Default behaviour $
A newMethod metódust nem kellett implementálnunk, s a futtatás során lefutott a általunk megadott alapértelmezett metódustörzs.
Implementáció két metódussal
Amint az kitalálható: ha implementáljuk az új metódust is...
public class LambdaImplementation implements LambdaInterface { public void oldMethod() { System.out.println("Implemented oldMethod"); } public void newMethod() { System.out.println("Implemented newMethod"); } }
...akkor az implementáció metódustörzse fog lefutni:
$ /opt/jdk1.8.0/bin/javac LambdaImplementation.java $ /opt/jdk1.8.0/bin/java LambdaRun Implemented oldMethod Implemented newMethod
Vélemény?
Ha egy meglévő interfész kibővítésére volt szükségünk, akkor két lehetőségünk volt:
- megkeressük az összes leszármazottat, ahol implementálunk egy üres metódust
- létrehoztunk egy új interfészt a régi mellé, és a régit békén hagytuk
Ez a megoldás hasznos dolognak tűnik... szerinted is?