Default metod java 8 ilə yeni gələn özəlliklərdən biridir. Default metod interface`in daxilində default
açar sözü ilə tanımlanan və gövdəsi olan metoddur. Interface`i implements
edən classların default
metodu override etmək kimi bir məcburiyyəti yoxdur. Classların sərbəst seçimi var, istəsə override edə bilər, istəməsə yox. Əgər override etməsə, o zaman interface`də tanımlanan default
metod istifadə ediləcəkdir. Sintaksisi aşağıdakı kimidir:
public interface DefaultMethod { public int getCount(); public default int getNumber(){ return 7; } public default void showNumber(); // DOES NOT COMPILE public String getName(){ // DOES NOT COMPILE return "Ülvi"; } }
Default metodlar üçün aşağıdakı qaydalar mövcuddur:
- Default metod ancaq interface daxilində elan edilə bilər, class və abstract class daxilində elan edilə bilməz;
- Default metodlar
default
açar sözü ilə işarələnməlidir və əgərdefault
açar sözü ilə işarələnibsə, mütləq gövdəsi olmalıdır; - Default metodların
static
,final
və yaabstract
olduğu fərz edilməməlidir (daha dəqiq desək default metodlarla bu açar sözlərin birgə istifadəsinə icazə verilmir), onlar interface`iimplements
edən class tərəfindən istifadə edilə və ya override oluna bilər; - Bütün interface metodları kimi
default
metodların dapublic
olduğu fərz edilməlidir. Və bu səbəbdənprivate
və yaprotected
kimi işarələnəndefault
metodlar compile olunmur.
Əgər hər hansı bir interface, daxilində default
metod olan başqa bir interface`i extends
edərsə, həmin default
metod ilə bir neçə cür davrana bilər:
default
metodla bağlı hər hansı bir davranışdan imtina edə bilər, bu zaman originaldefault
metod üçün tanımlanmış gövdə istifadə olunur;default
metodu yenidən override edə bilər;default
metodu yenidənabstract
metod kimi tanımlaya bilər. Belə olduqda isə artıq ikinci interface`iimplements
edən class həmin metodu override etmək məcburiyyətindədir.
Nümunə:
public interface HasFins { default int getInt() { return 1; } public default double getDouble() { return 2; } default public boolean getBoolean() { return true; } } interface SharkFamily extends HasFins { int getInt(); default double getDouble() { return 5; } } class TestHasFins implements HasFins { } class TestSharkFamily implements SharkFamily { TestSharkFamily() { System.out.println(getDouble()); // 5.0 } public int getInt() { return 7; } public static void main(String args[]) { new TestSharkFamily(); } }
Interface’in default
metodlarını həmin interface’i implements
edən konkret class daxilində super
açar sözü ilə çağırmaq mümkün deyil. super
açar sözü ancaq classlar üçün istifadə edildikdə düzgün işləyir. Əgər default
metodlar üçün istifadə etmək istəyiriksə, mütləq super
açar sözünün qarşısında həmin interface’in adını qeyd etmək lazımdır:
interface Walk { public default int getSpeed() { return 10; } } abstract class Animal { public String getColor(){ return "black"; } } class Cat extends Animal implements Walk { public Cat() { System.out.println(this.getColor()); System.out.println(super.getColor()); System.out.println(this.getSpeed()); System.out.println(super.getSpeed()); // DOES NOT COMPILE System.out.println(Walk.super.getSpeed()); } }
MyExamCloud’da suallardan birində maraqlı bir faktla qarşılaşmışdım. Deməli, faktda qeyd olunurdu ki, siz interface’də default
metodları java.lang.Object
classına aid (final
olmayan) hər hansı bir metodu override etmək üçün istifadə edə bilməzsiniz, əks halda compile xətası alacaqsınız:
interface A { int groupID = 10; default boolean equals(Object obj) { // DOES NOT COMPILE return this.groupID == ((A) obj).groupID; } static void print() { System.out.println("A"); } }
Default Methods and Multiple Inheritance
Əvvəlki mövzulardan birində qeyd etdik ki, hər hansı bir class tərəfindən implements
olunan interface`lərdə eyni abstract
metodlar olarsa, problemsiz compile olunur, çünki dublikat metodlar sayılır. Amma default
metodlarla vəziyyət nisbətən fərqlidir. Compiler eyni default
metodlar aşkarladıqda xəta verir:
interface Walk { public default int getSpeed() { return 10; } } interface Run { public default int getSpeed() { return 20; } } public class Cat implements Walk, Run { // DOES NOT COMPILE public static void main(String[] args){ System.out.println(new Cat().getSpeed()); } }
Bu nümunədə Cat
classı iki eyni default
metodu (getSpeed()
) irs alır, amma təyin edə bilmir ki, hansı metodu istifadə etməlidir, 10
çap olunmalıdı ya 20
?! Ona görə də compiler belə konfliktlə rastlaşdıqda xəta verir. Amma burada bir istisna var: əgər subclass konflikt yaradan default
metodu (getSpeed()
) override etsə, o zaman bu kod heç bir problem olmadan compile olunacaqdır:
public class Cat implements Walk, Run { public int getSpeed(){ return 30; } public static void main(String[] args){ System.out.println(new Cat().getSpeed()); // 30 } }
[topics lang=az]