CodeGym /Kurslar /Java SELF AZ /İnterfeyslərin mahiyyəti

İnterfeyslərin mahiyyəti

Java SELF AZ
Səviyyə , Dərs
Mövcuddur

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.

İnterfeyslərin mahiyyəti

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
interface Movable
{
   void move(String newAddress);
}
hərəkət edə bilmək bacarığına uyğundur
interface Driveable
{
   void drive(Driver driver);
}
sürücü tərəfindən idarə olunma bacarığına uyğundur
interface Transport
{
   void addStuff(Object stuff);
   Object removeStuff();
}
yük daşıma bacarığına uyğundur
class Wheel implements Movable
{
   ...
}
Wheel (təkər) sinfi hərəkət edə bilmək bacarığına malikdir
class Car implements Movable, Driveable, Transport
{
   ...
}
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
class Skateboard implements Movable, Driveable
{
   ...
}
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 interfeysrollar 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
interface Səs
{
   void səs();
}
Səs bacarığı. səs əmri başa düşülür — müvafiq metodu var.
class Pişik implements Səs
{
   void səs()
   {
      println("MİYYAU");
   }
}

class İt implements Səs
{
   void səs()
   {
      println("HAV-HAV");
   }
}

class Balıq
{
   ...
}
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.













Bizim Balıq danışmaq bacarığına malik deyil (interfeys Səs-i həyata keçirmir).

public static void main(String[] args)
{
   // bütün heyvanları siyahıya əlavə edirik
   ArrayList evHeyvanlar = new ArrayList();
   evHeyvanlar.add(new Pişik());
   evHeyvanlar.add(new İt());
   evHeyvanlar.add(new Balıq());

   // əgər bu bacarıq varsa, qışqır
   for(Object evHeyvanı: evHeyvanlar)
   {
      if (evHeyvanı instanceof Səs)
      {
         Səs qışqıran = (Səs) evHeyvanı;
         qışqıran.səs();
      }
   }
}
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, InputStreamOutputStream 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.



Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION