JavaRush /Java Blogu /Random-AZ /Metod imzası

Metod imzası

Qrupda dərc edilmişdir
Salam! Siz artıq sahələr və üsullarla öz siniflərinizi yaratmağı mənimsəmişsiniz. Bu gün üsullar haqqında ətraflı danışacağıq. Biz, əlbəttə ki, mühazirələrimizdə bunu bir neçə dəfə etmişik, lakin biz əsasən ümumi məqamlardan danışmışıq. Bu gün biz üsulları sözün əsl mənasında "hissələrdə" təhlil edəcəyik - onların nədən ibarət olduğunu, onları yaratmaq üçün hansı variantların mövcud olduğunu və bütün bunların necə idarə oluna biləcəyini öyrənəcəyik :) Gedək!Metod imzası - 1

Metod imzası

Bir metodu təsvir edən bütün kodlara metod bəyannaməsi deyilir . Metod imzası müəyyən qaydada metod adını və parametr növlərini ehtiva edir. Reklamın ümumi görünüşünü aşağıdakı kimi təsvir etmək olar:
модификатор доступа, тип возвращаемого значения, Name метода(список параметров) {
    // тело метода
}
Sinfin bir neçə metodunun bəyannaməsinə nümunə götürək Dog.
public class Dog {

   String name;

   public Dog(String name) {
       this.name = name;
   }

   public static void main(String[] args) {
       Dog max = new Dog("Max");
       max.woof();

   }

   public void woof() {
       System.out.println("Собака по имени " + name + " говорит \"Гав-гав!\"");
   }

   public void run(int meters) {
       System.out.println("Собака по имени " + name + " пробежала " + meters + " метров!");
   }

   public String getName() {
       return name;
   }
}

1. Giriş dəyişdiricisi

Giriş modifikatoru həmişə ilk olaraq siyahıya alınır. Bütün sinif metodları Dogdəyişdirici tərəfindən təyin edilir public. Yəni biz onları istənilən başqa sinifdən çağıra bilərik:
public class Main {

   public static void main(String[] args) {

       Dog butch = new Dog("Бутч");
       butch.run(100);
   }

}
Sinif metodları Dog, gördüyünüz kimi, sinifdə asanlıqla əldə edilə bilər Main. Bu, dəyişdirici sayəsində mümkündür public. Java-da başqa modifikatorlar var və onların heç də hamısı başqa sinif daxilində metoddan istifadə etməyə imkan verməyəcək. Digər mühazirələrdə onlar haqqında danışacağıq. Əsas odur ki, dəyişdiricinin nəyə cavabdeh olduğunu xatırlayın: metodun digər siniflərdə mövcudluğu/əlçatmazlığı :)

2. Statik açar söz

Metodlardan biri Dog, yəni main()açar sözlə göstərilir static. Əgər mövcuddursa, o zaman giriş dəyişdiricisindən sonra göstərilməlidir. Əvvəlki mühazirələrdə statik sinif dəyişənləri haqqında danışdığımızı xatırlayırsınız? Metodlara tətbiq edildikdə bu söz təxminən eyni məna daşıyır. Metod kimi göstərilibsə static, bu o deməkdir ki, o, müəyyən bir sinif obyektinə istinad etmədən istifadə edilə bilər. Və həqiqətən, main()bir sinifdə statik bir metodu işə salmaq üçün Dogbir nümunə yaratmağa ehtiyac yoxdur Dog; onsuz da işləyir. Əgər bu üsul statik olmasaydı, ondan istifadə etmək üçün əvvəlcə obyekt yaratmalıyıq.

3. Dəyəri qaytarın.

Əgər metodumuz nəyisə qaytarmalıdırsa, onda biz qaytarılan dəyərin növünü göstəririk. Bunu alıcının nümunəsində görmək olar getName():
public String getName() {
   return name;
}
O, tipli obyekti qaytarır String. Metod heç nə qaytarmırsa, voidmetodda olduğu kimi type əvəzinə açar söz təyin olunur woof():
public void woof() {
   System.out.println("Собака по имени " + name + " говорит \"Гав-гав!\"");
}

Eyni adlı üsullar

Proqramımızın metodun necə işləməsi üçün bir neçə variant tələb etdiyi vəziyyətlər var. Niyə öz süni intellektimizi yaratmırıq? Amazonda Alexa var, Yandex-də Alice var, bəs biz niyə daha pisik? :) Dəmir adam haqqında filmdə Toni Stark özünün görkəmli süni intellektini yaradıb - JARVIS Gəlin gözəl personajı xatırlayaq və süni intellektimizi onun şərəfinə adlandıraq :) Jarvisə öyrətməli olduğumuz ilk şey - otağa daxil olan insanlarla salamlaşmaq (belə bir böyük intellektin nəzakətsiz olduğu ortaya çıxsa, qəribə olardı).
public class Jarvis {

   public void sayHi(String name) {
       System.out.println("Good evening, " + name + ", How are you doing?");
   }

   public static void main(String[] args) {
       Jarvis jarvis = new Jarvis();
       jarvis.sayHi("Tony Stark");
   }
}
Konsol çıxışı:

Добрый вечер, Тони Старк, How ваши дела?
Əla! Jarvis içəri girən adamı necə qarşılamağı bilir. Çox vaxt, əlbəttə ki, onun sahibi olacaq - Tony Stark. Ancaq o, tək gəlməyə bilər! Bizim metodumuz sayHi()giriş kimi yalnız bir arqument alır. Və buna uyğun olaraq, gələnlərdən yalnız birinə salam verə biləcək, digərinə məhəl qoymayacaq. Çox nəzakətli deyiləm, razıyam?:/ Bu halda problemi həll etmək üçün sadəcə olaraq sinifdə eyni adlı, lakin fərqli parametrlərlə 2 metod yaza bilərik:
public class Jarvis {

   public void sayHi(String firstGuest) {
       System.out.println("Good evening, " + firstGuest + ", How are you doing?");
   }

   public void sayHi(String firstGuest, String secondGuest) {
       System.out.println("Good evening, " + firstGuest + ", " + secondGuest + ", How are you doing?");
   }

}
Buna metodun həddindən artıq yüklənməsi deyilir . Həddindən artıq yükləmə proqramımızın daha çevik olmasına və müxtəlif iş variantlarını yerləşdirməyə imkan verir. Bunun necə işlədiyini yoxlayaq:
public class Jarvis {

   public void sayHi(String firstGuest) {
       System.out.println("Good evening, " + firstGuest + ", How are you doing?");
   }

   public void sayHi(String firstGuest, String secondGuest) {
       System.out.println("Good evening, " + firstGuest + ", " + secondGuest + ", How are you doing?");
   }

   public static void main(String[] args) {
       Jarvis jarvis = new Jarvis();
       jarvis.sayHi("Tony Stark");
       jarvis.sayHi("Tony Stark", "Captain America");
   }
}
Konsol çıxışı:

Добрый вечер, Тони Старк, How ваши дела? 
Добрый вечер, Тони Старк, Капитан Америка, How ваши дела?
Əla, hər iki variant işlədi :) Lakin, problemi həll etmədik! Üç qonaq olsa nə olar? sayHi()Əlbəttə ki, üç qonağın adını qəbul etmək üçün üsulu yenidən yükləyə bilərik . Ancaq bunlardan 4 və ya 5 ola bilər.Və s sonsuza qədər. Jarvisə milyonlarla metod yüklənmədən istənilən sayda adla işləməyi öyrətməyin başqa yolu varmı sayHi()? :/ Əlbəttə var! Əks halda Java dünyanın ən populyar proqramlaşdırma dili olardımı? ;)
public class Jarvis {

   public void sayHi(String...names) {

       for (String name: names) {
           System.out.println("Good evening, " + name + ", How are you doing?");
       }
   }

   public static void main(String[] args) {
       Jarvis jarvis = new Jarvis();
       jarvis.sayHi("Tony Stark");
       System.out.println();
       jarvis.sayHi("Tony Stark", "Captain America");
   }
}
Parametr kimi ötürülən qeyd ( String...names) bizə müəyyən sayda sətirlərin metoda ötürüldüyünü bildirməyə imkan verir. Nə qədər olacağını əvvəlcədən dəqiqləşdirmirik, buna görə də metodumuzun işi indi daha çevik olur:
public class Jarvis {

   public void sayHi(String...names) {

       for (String name: names) {
           System.out.println("Good evening, " + name + ", How are you doing?");
       }
   }

   public static void main(String[] args) {
       Jarvis jarvis = new Jarvis();
       jarvis.sayHi("Tony Stark", "Captain America", "Black Widow", "Hulk");
   }
}
Konsol çıxışı:

Добрый вечер, Тони Старк, How ваши дела? 
Добрый вечер, Капитан Америка, How ваши дела? 
Добрый вечер, Черная Вдова, How ваши дела? 
Добрый вечер, Халк, How ваши дела?
Metodun içərisində biz bütün arqumentləri dövrələyirik və adları olan hazır ifadələri konsola çıxarırıq. Burada biz sadələşdirilmiş döngədən istifadə edirik for-each(siz artıq onunla qarşılaşmısınız). Əladır, çünki yazmaq String...namesəslində bütün ötürülən parametrlərin kompilyator tərəfindən massivə salınması deməkdir. Beləliklə, namessiz dəyişənlə massivdə olduğu kimi işləyə bilərsiniz, o cümlədən onun üzərindən dövrə vurmaq. Üstəlik, istənilən sayda köçürülmüş xətlər üçün işləyəcək! İki, on, hətta min - üsul istənilən sayda qonaqla etibarlı şəkildə işləyəcək. Bütün mümkün variantlar üçün həddən artıq yükləmələr etməkdən daha rahatdır, razı deyilsiniz? :) Metodun həddindən artıq yüklənməsinə başqa bir misal verək. Jarvisə bir üsul əlavə edək printInfoFromDatabase(). O, verilənlər bazasından konsola şəxs haqqında məlumatları çap edəcək. Əgər verilənlər bazası şəxsin super qəhrəman və ya super cani olduğunu göstərirsə, bu məlumat da ekranda görünəcək:
public class Jarvis {

   public  void printInfoFromDatabase (String bio) {

       System.out.println(bio);
   }

   public void printInfoFromDatabase(String bio, boolean isEvil, String nickname) {

       System.out.println(bio);
       if (!isEvil) {
           System.out.println("Также известен How супергерой " + nickname);
       } else {
           System.out.println("Также известен How суперзлодей " + nickname);
       }
   }

   public static void main(String[] args) {
       Jarvis jarvis = new Jarvis();
       jarvis.printInfoFromDatabase("Лора Палмер. Дата рождения - 22 июля 1972, город Твин Пикс, штат Washington");
       System.out.println();
       jarvis.printInfoFromDatabase("Макс Эйзенхарт. Рост 188см, вес 86 кг.", true, "Магнето");
   }
}
Nəticə:

Лора Палмер. Дата рождения - 22 июля 1972, город Твин Пикс, штат Washington
Макс Эйзенхарт. Рост 188см, вес 86 кг 
Также известен How суперзлодей Магнето
Metodumuz daxil etdiyimiz məlumatlardan asılı olaraq belə işləyir. Başqa bir vacib məqam:Mübahisələrin ardıcıllığı önəmlidir! Deyək ki, metodumuz giriş kimi bir sətir və bir ədəd götürür:
public class Man {

   public static void sayYourAge(String greeting, int age) {
       System.out.println(greeting + " " + age);
   }

   public static void main(String[] args) {

       sayYourAge("My age - ", 33);
       sayYourAge(33, "My age - "); //error!
   }
}
sayYourAge()Sinif metodu giriş kimi sətir və rəqəm götürürsə Man, proqramda onların ötürülməsi lazım olan ardıcıllıq budur! Onları fərqli ardıcıllıqla keçirsək, tərtibçi xəta atacaq və adam öz yaşını deyə bilməyəcək. Yeri gəlmişkən, sonuncu mühazirədə bəhs etdiyimiz konstruktorlar da üsullardır! Onlar həmçinin həddən artıq yüklənə bilər (müxtəlif arqumentlər dəsti ilə bir neçə konstruktor yarada) və onlar üçün arqumentlərin ötürülməsi sırası da əsaslı əhəmiyyət kəsb edir. Əsl üsullar! :)

Bənzər parametrləri olan metodları necə çağırmaq olar

Bildiyiniz kimi Java-da null kimi bir söz var. Onunla işləyərkən nullun nə obyekt, nə də məlumat tipi olmadığını başa düşmək çox vacibdir. Təsəvvür edin ki, bizdə bir sinif Adamı və introduce()bir insanın adını və yaşını elan edən bir üsul var. Bu zaman yaş mətn şəklində verilə bilər, yaxud rəqəmlə ifadə oluna bilər.
public class Man {

   public void introduce(String name, String age) {
       System.out.println("Меня зовут " + name + ", мой возраст - " + age);
   }

   public void introduce(String name, Integer age) {
       System.out.println("Меня зовут " + name + ", мой возраст - " + age);
   }

   public static void main(String[] args) {

       Man sasha = new Man();
       sasha.introduce("Sasha", "двадцать один");

       Man masha = new Man();
       masha.introduce("Мария", 32);
   }
}
Biz artıq yüklənmə ilə tanışıq, ona görə də bilirik ki, metod hər iki dəfə gözlənildiyi kimi işləyəcək:

Меня зовут Саша, мой возраст - двадцать один 
Меня зовут Мария, мой возраст - 32 
Bəs sətir və ya rəqəmi deyil, ikinci parametr kimi null-u keçsək nə olar?
public static void main(String[] args) {

   Man victor = new Man();
   victor.introduce("Виктор", null);//Ambiguous method call!
}
Kompilyasiya xətası alacağıq! “Qeyri-müəyyən metod çağırışı” xətası “birmənalı metod çağırışı” kimi tərcümə olunur. Niyə yarana bilər və “qeyri-müəyyənlik” nədir? Əslində sadədir. İş ondadır ki, metodun iki variantımız var: ikinci arqument olaraq ilə Stringvə ilə . IntegerAmma hər ikisi StringIntegernull ola bilər! Hər iki növ üçün (onlar istinad növləri olduğundan) null standart dəyərdir. Buna görə də bu vəziyyətdə tərtibçi metodun hansı versiyasını çağırmalı olduğunu anlaya bilmir. Bu problemin həlli olduqca sadədir. Məsələ ondadır ki, null açıq şəkildə müəyyən bir istinad növünə çevrilə bilər. Buna görə də, metodu çağırarkən, ikinci arqument üçün lazım olan məlumat tipini mötərizədə göstərə bilərsiniz! Kompilyator "işarəni" başa düşəcək və tələb olunan metodu çağıracaq:
public class Man {

   public void introduce(String name, String age) {
       System.out.println("Метод с двумя строками!");
       System.out.println("Меня зовут " + name + ", мой возраст - " + age);
   }

   public void introduce(String name, Integer age) {
       System.out.println("Метод со строкой и числом!");
       System.out.println("Меня зовут " + name + ", мой возраст - " + age);
   }

   public static void main(String[] args) {

       Man victor = new Man();
       victor.introduce("Виктор", (String) null);
   }
}
Nəticə:

Метод с двумя строками! 
Меня зовут Виктор, мой возраст - null
intLakin rəqəmli parametr istinad tipli obyekt deyil, primitiv olsaydı Integer, belə bir xəta baş verməzdi.
public class Man {

   public void introduce(String name, String age) {
       System.out.println("Метод с двумя строками!");
       System.out.println("Меня зовут " + name + ", мой возраст - " + age);
   }

   public void introduce(String name, int age) {
       System.out.println("Метод со строкой и числом!!");
       System.out.println("Меня зовут " + name + ", мой возраст - " + age);
   }

   public static void main(String[] args) {

       Man victor = new Man();
       victor.introduce("Виктор", null);
   }
}
Səbəbini təxmin etdinizmi? Əgər təxmin etmisinizsə, afərin :) Çünki primitivlər sıfıra bərabər ola bilməz. İndi kompilyatorda metodu çağırmaq üçün yalnız bir seçim var introduce()- iki sətirlə. Metodun hər dəfə çağırıldığı zaman işlənəcək metodun bu versiyasıdır.
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION