Salam! Siz artıq Java-da metodlardan istifadə edirsiniz və onlar haqqında çox şey bilirsiniz. Yəqin ki, bir sinifdə eyni adlı, lakin fərqli arqumentlər olan bir çox metodun olduğu bir vəziyyətlə qarşılaşmısınız. Xatırlayırsınızsa, o hallarda biz həddindən artıq yükləmə mexanizmindən istifadə etdik. Bu gün fərqli bir vəziyyətə baxaq. Təsəvvür edin ki, bizim bir ümumi metodumuz var, lakin hansı sinifə çağırıldığından asılı olaraq fərqli işlər görməlidir. Bu davranışı necə həyata keçirmək olar? Bunu anlamaq üçün heyvanları ifadə edən valideyn sinfini götürək Animalvə orada bir üsul yaradaq voice- “ səs ”:
public class Animal {

   public void voice() {

       System.out.println("Voice!");
   }
}
Proqramı yenicə yazmağa başlasaq da, çox güman ki, potensial problemi görə bilərsiniz: dünyada çoxlu heyvanlar var və onların hamısı fərqli “danışır”: pişiklər miyavlayır, ördəklər şarladır, ilanlar fısıldayır. Metodun üstünlüyü mexanizmi necə işləyir - 2 Məqsədimiz sadədir: səs vermək üçün bir dəstə üsul yaratmaqdan çəkinin. voiceCat()Miyavlama, voiceSnake()fısıltı və s üsullar yaratmaq əvəzinə , voice()üsul çağırılan zaman ilanın, pişiyin miyavlamasını, itin hürməsini istəyirik. Biz buna asanlıqla metodu ləğvetmə mexanizmindən istifadə edə bilərik (Java-da Override) . Vikipediya “əsas alma” termininin aşağıdakı izahını verir: Obyekt yönümlü proqramlaşdırmada metodun üstünlüyü, alt sinifə və ya uşaq sinfə yuxarı siniflərdən birində artıq tətbiq edilmiş metodun xüsusi həyata keçirilməsini təmin etməyə imkan verən proqramlaşdırma dilinin xüsusiyyətlərindən biridir. və ya valideyn sinifləri. Ümumiyyətlə, düzgündür. Üstündən təyinetmə sizə valideyn sinfinin metodunu götürməyə və hər bir nəsil sinfində bu metodun öz tətbiqini yazmağa imkan verir. Yeni tətbiq uşaq sinfində valideyni "əvəz edəcək". Bir nümunə ilə bunun necə göründüyünü görək. Sinifimiz üçün 4 ardıcıl sinif yaradaq : Animal
public class Bear extends Animal {
   @Override
   public void voice() {
       System.out.println("Р-р-р!");
   }
}
public class Cat extends Animal {

   @Override
   public void voice() {
       System.out.println("Meow!");
   }
}

public class Dog extends Animal {

   @Override
   public void voice() {
       System.out.println("Woof!");
   }
}


public class Snake extends Animal {

   @Override
   public void voice() {
       System.out.println("Ш-ш-ш!");
   }
}
Gələcək üçün kiçik bir həyat hacki: ana sinifin metodlarını ləğv etmək üçün Intellij IDE a -da nəsil sinfin koduna keçin , Ctrl+O düymələrini basın və menyudan “ Metodları ləğv et... ” seçin. Əvvəldən isti düymələrdən istifadə etməyə alışın, bu proqramların yazılmasını sürətləndirəcək! İstədiyimiz davranışı qurmaq üçün bir neçə şey etdik:
  1. Biz hər bir nəsil sinfində ana sinifdəki metodla eyni adda bir metod yaratdıq.
  2. Kompilyatora dedik ki, metodu ana sinifdəki kimi adlandırdıq: biz onun davranışını ləğv etmək istədik. Kompilyatora bu "mesaj" üçün metoda @Override annotasiyası qoyuruq .
    Metodun üstündə yerləşdirilmiş @Override annotasiyası tərtibçiyə (və kodunuzu oxuyan proqramçılara da) deyir: “Hər şey qaydasındadır, bu səhv və ya mənim unutqanlığım deyil. Yadımdadır ki, belə bir üsul artıq mövcuddur və mən onu ləğv etmək istəyirəm”.

  3. Hər bir nəsil sinfi üçün lazım olan tətbiqi yazdıq. Çağırılanda ilan voice()fısıldamalı, ayı nərilməlidir və s.
Bunun proqramda necə işləyəcəyini görək:
public class Main {

   public static void main(String[] args) {

       Animal animal1 = new Dog();
       Animal animal2 = new Cat();
       Animal animal3 = new Bear();
       Animal animal4 = new Snake();

       animal1.voice();
       animal2.voice();
       animal3.voice();
       animal4.voice();
   }
}
Konsol çıxışı: Vay! Miyav! Rrrr! şşşş! Əla, hər şey lazım olduğu kimi işləyir! Biz ana sinifin 4 istinad dəyişənini yaratdıq Animalvə onları nəsil siniflərin 4 müxtəlif obyektinə təyin etdik. Nəticədə hər bir obyekt fərqli davranır. Nəsil siniflərinin hər biri üçün ləğv edilmiş metod sinifdən voice()“doğma” metodu əvəz etdi (sadəcə konsola “Səs!” verir). Üstündən təyinetmə bir sıra məhdudiyyətlərə malikdir: voice()AnimalMetodun üstünlüyü mexanizmi necə işləyir - 3
  1. Üstündən təyin edilmiş metod ana metodla eyni arqumentlərə malik olmalıdır.

    voiceAna sinifdəki metod giriş kimi qəbul edərsə String, uşaq sinifdə ləğv edilmiş metod da giriş kimi qəbul etməlidir String, əks halda kompilyator xəta atacaq:

    public class Animal {
    
       public void voice(String s) {
    
           System.out.println("Voice! " + s);
       }
    }
    
    public class Cat extends Animal {
    
       @Override//error!
       public void voice() {
           System.out.println("Meow!");
       }
    }

  2. Yenidən təyin edilmiş metod ana metodla eyni qaytarma növünə malik olmalıdır.

    Əks halda, tərtib etmə xətası alacağıq:

    public class Animal {
    
       public void voice() {
    
           System.out.println("Voice!");
       }
    }
    
    
    public class Cat extends Animal {
    
       @Override
       public String voice() {         //error!
           System.out.println("Meow!");
           return "Meow!";
       }
    }

  3. Ləğv edilmiş metodun giriş modifikatoru da “orijinal”dan fərqlənə bilməz:

    public class Animal {
    
       public void voice() {
    
           System.out.println("Voice!");
       }
    }
    
    public class Cat extends Animal {
    
       @Override
       private void voice() {      //error!
           System.out.println("Meow!");
       }
    }
Java-da metodun üstünlüyü polimorfizm ideyasını həyata keçirmək üçün vasitələrdən biridir (son mühazirədə danışdığımız OOP prinsipi). Buna görə də, ondan istifadə etməyin əsas üstünlüyü əvvəllər danışdığımız eyni elastiklik olacaqdır. Biz sadə və məntiqi siniflər sistemi qura bilərik, onların hər birinin özünəməxsus davranışı (itlər hürər, pişiklər miyavlayır), lakin vahid interfeyslə - bir voice()dəstə metod əvəzinə hamı üçün bir üsul və s voiceDog().voiceCat()