Interface(Arayüz) nedir sorusuna Oracle aşağıdaki şekilde cevap vermektedir.
An interface is a group of related methods with empty bodies.
Fakat bu tanım Java 1.7 ve önceki versiyonları için yapılmıştır. Java 8, Interfacelerde yeni bir default(varsayılan) ve statik yöntem sağlamaktadır ve bu sayede interfacelere gövdeli metot yazılabilmektedir. Stream özelliğini sağlamak ve geriye dönük uyumluluk için eklenmiştir.
Interface’leri tasarlamak zorlu bir iştir çünkü eğer interfacelere ek yöntemler eklemek istiyorsak, implement eden tüm sınıflarda değişiklik yapılması gerekmektedir. Default(Varsayılan) interface yöntemleri, bu sorunla başa çıkmak için etkili bir yoldur. Uygulamalarda otomatik olarak kullanılabilen bir arayüze yeni yöntemler eklememize izin veriyorlar. Böylece, uygulama sınıflarını değiştirmeye gerek yoktur. Bu şekilde, geriye doğru uyumluluk ve uygulama sınıflarını kırma korkusu olmadan interfaceleri genişletmemize yardımcı olacaktır. Yani, interfacelerde bu default kavramını çıkarmasaydılar Java 8’e yükseltme herkes için çok sancılı olacaktı.
Varsayılan yöntemler birçok farklı isim ile anılmaktadır. Bunlar;
- Default method
- Defender method
- Virtual extension method
Java interface statik yöntemi, varsayılan yönteme benzerdir. Tek farkı Default(varsayılan) yöntemler override edilebilir fakat statik yöntemler override edilemez. Bunun sebebi ise uygulama sınıflarının bunları geçersiz kılmasına izin vermeyerek güvenlik sağlamada bize yardımcı olur.
Örnek yapalım.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public interface InterfaceA { void greeting(String str); default void print(){ control(); System.out.println("InterfaceA"); } static void control(){ System.out.println("Controlled"); } } |
Test sınıfımız da aşağıdaki şekilde olsun ve çıktısına bakalım.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public class DefaultTest implements InterfaceA { public static void main(String[] args) { DefaultTest defaultTest = new DefaultTest(); defaultTest.greeting("Koray"); defaultTest.print(); } @Override public void greeting(String str) { System.out.println("Hello, " + str); } } |
Çıktı aşağıdaki gibi olacaktır.
1 2 3 |
Hello, Koray Controlled InterfaceA |
Varsayılan yöntemlerin çakışması
Java 8 ile beraber default(varsayılan) gövdeli metotlar geldikten sonra olmazsa olmaz Conflict(çakışma) durumu ile karşılaşılacaktı. Sebebi aynı isimde iki varsayılan metoda sahip iki interface’imiz olsun. Bu interfaceleri implement ettiğimde hangi varsayılan metodu kullanacağım?
JVM’ de aynı bu şekilde yorumlayarak derleme anında sizden karar vermenizi isteyecektir. İşte bu noktada <arayüz-adı>.super.<metod-adı>()
biçimi ile arayüzlerdeki varsayılan metodlar çakışma olmadan çağırabilmektedir.
1 2 3 4 5 6 7 |
public interface InterfaceB { default void print(){ System.out.println("InterfaceB"); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
public class DefaultTest implements InterfaceA, InterfaceB{ public static void main(String[] args) { DefaultTest defaultTest = new DefaultTest(); defaultTest.greeting("Koray"); defaultTest.print(); } @Override public void greeting(String str) { System.out.println("Hello, " + str); } @Override public void print() { InterfaceA.super.print(); // veya InterfaceB.super.print(); } } |