1. Bacarıqlar
İnterfeyslərin üstünlüklərini və istifadə olunduğu yerləri daha yaxşı başa düşmək üçün daha abstrakt şeylərdən danışmalıyıq.
Sinif — çox vaxt konkret bir obyektin modelidir. İnterfeys isə daha çox obyektlərin özlərinə deyil, onların bacarıqlarına və ya rollarına uyğundur.

Məsələn, maşın, velosiped, motosiklet və təkər kimi şeyləri siniflər və obyektlər kimi təsəvvür etmək daha yaxşıdır. Amma «hərəkət edə bilərəm», «adam daşıya bilərəm», «dayana bilərəm» kimi bacarıqlarını interfeys şəklində təqdim etmək daha məntiqlidir. Budur bir neçə nümunə:
Kod | Təsvir |
---|---|
|
hərəkət edə bilmək bacarığına uyğundur |
|
sürücü tərəfindən idarə olunma bacarığına uyğundur |
|
yük daşıma bacarığına uyğundur |
|
Wheel (təkər) sinfi hərəkət edə bilmək bacarığına malikdir |
|
Car (maşın) sinfi hərəkət edə bilmək, insan tərəfindən idarə olunmaq və yük daşımaq bacarıqlarına malikdir |
|
Skateboard (skeytbord) sinfi hərəkət edə bilmək və insan tərəfindən idarə olunmaq bacarıqlarına malikdir |
2. Rollar
İnterfeyslər proqramçının işini çox asanlaşdırır. Çox vaxt proqramda minlərlə obyekt, yüzlərlə sinif və cəmi bir neçə on interfeys — rollar olur. Rolların sayı azdır, amma onların kombinasiyaları — siniflər — çoxdur.
Bütün məna ondadır ki, sizə bütün siniflərin bir-biri ilə qarşılıqlı əlaqəsini yazmaq lazım deyil. Siz sadəcə onların rolları (interfeysləri) ilə qarşılıqlı əlaqə qurmalısınız.
Təsəvvür edin ki, siz ev heyvanlarını öyrədirsiniz və hər birinin bir neçə fərqli bacarığı ola bilər. Və qonşunuzla heyvanların kim daha yüksək səslə qışqırır deyə mübahisə edirsiniz. Sadəcə "səs" bacarığı olanları götürürsünüz və onlara əmr edirsiniz: Səs!.
Sizə fərq etməz, həmin heyvanlar kimdir və onların hansı digər bacarıqları var. Hətta geriyə üçqat salto da ola bilər. Hazırda sizi yalnız yüksək səslə qışqırmaq bacarığı maraqlandırır. Kodda bu belə görünərdi:
Kod | Təsvir |
---|---|
|
Səs bacarığı. səs əmri başa düşülür — müvafiq metodu var. |
|
Bu bacarığa malik heyvanlar. Asanlıq üçün siniflərə Azərbaycan dilində adlar verdik. Bu, Java-da icazəlidir, amma çox məsləhət görülmür.
|
|
Onlara necə əmr verək? |
Müxtəlif siniflərin sayı minlərlə olmağa başladıqda, interfeyslərsiz yaşaya bilməyəcəksiniz. Minlərlə sinifin qarşılıqlı əlaqəsini təsvir etməkdənsə, cəmi bir neçə on interfeysin əlaqələrini təsvir etmək kifayətdir — bu, həyatı çox asanlaşdırır.
Və polimorfizmlə birlikdə — bu, ümumiyyətlə bombadır.
3. default
interfeyslərin metodlarında realizasiya
Abstrakt siniflərdə dəyişənlər və metodların realizasiyası ola bilər, amma onlarda çoxlu miras qadağandır. İnterfeyslərdə isə dəyişənlər və metodların realizasiyası olmaz, amma çoxlu mirasa icazə var.
Bu vəziyyəti cədvəllə ifadə edə bilərik:
Bacarıq | Abstrakt siniflər | İnterfeyslər |
---|---|---|
Dəyişənlər | ✔ | ✖ |
Metodların realizasiyası | ✔ | ✖ |
Çoxlu miras | ✖ | ✔ |
Və bəzi proqramçılar çox istəyirdilər ki, interfeyslərdə metodların realizasiyası imkanı olsun. Metodun realizasiyası əlavə etmək imkanı o demək deyil ki, bunu həmişə etmək məcburidir. İstəyirsən et, istəmirsən etmə.
Üstəlik, çoxlu miras ilə bağlı problemlər əsasən dəyişənlərdən qaynaqlanır. Ümumilikdə bunu düzəltmək qərarına gəldilər. JDK 8-dən başlayaraq, Java interfeyslərə metodların realizasiyasını əlavə etmək imkanı verdi.
Yeni aktual cədvəl (JDK 8 və sonrası üçün):
Bacarıq | Abstrakt siniflər | İnterfeyslər |
---|---|---|
Dəyişənlər | ✔ | ✖ |
Metodların realizasiyası | ✔ | ✔ |
Çoxlu miras | ✖ | ✔ |
İndi abstrakt siniflərdə, həm də interfeyslərdə həm realizasiyası olan, həm də olmayan metodları elan etmək olar. Və bu əla xəbərdir!
Abstrakt siniflərdə realizasiyası olmayan metodların qarşısında abstract
açar sözü yazılmalıdır, realizasiyası olan metodların qarşısında isə heç nə yazmaq lazım deyil. İnterfeyslərdə isə tam əksinə. Əgər metodun realizasiyası yoxdursa, heç nə yazmaq lazım deyil, realizasiyası varsa, default
açar sözü əlavə edilməlidir.
Sadələşdirmək üçün bu məlumatı kiçik bir cədvəllə təqdim edək:
Bacarıq | Abstrakt siniflər | İnterfeyslər |
---|---|---|
Realizasiyası olmayan metodlar | abstract |
– |
Realizasiyası olan metodlar | – | default |
Problem
İnterfeyslərlə metodlardan istifadə etməklə bir çox siniflərin iyerarxiyalarını xeyli sadələşdirmək olar. Məsələn, InputStream
və OutputStream
abstrakt siniflərini interfeys olaraq elan etmək olar! Bu, onları daha tez-tez və daha rahat istifadə etməyə imkan verəcək.
Amma dünyada artıq milyonlarla (milyardlarla?) Java sinifləri yazılıb. Əgər standart kitabxanaları dəyişməyə başlasalar, hər şey pozula bilər. Məsələn, hər şey! 😛
İşləyən proqramları və kitabxanaları təsadüfən sındırmamaq üçün qərara alındı ki, interfeyslərdə metodların realizasiyası mirasda ən aşağı prioritet alacaq.
Məsələn, metod ilə interfeysdən ikinci bir interfeysə miras alınarsa və orada bu metod realizasiyasız elan edilərsə, onda birinci metodun realizasiyası sinfə çatmaz. Nümunə:
interface Pet
{
default void meow()
{
System.out.println("Miyov");
}
}
interface Cat extends Pet
{
void meow(); // burada biz default realizasiyanı realizasiya etməmək ilə üstələmişik
}
class Barsik implements Cat
{
}
Kod kompilyasiya olunmayacaq, çünki Barsik
sinfində meow()
metodu realizasiya olunmayıb.
GO TO FULL VERSION