1. Metodların yüklənməsi
Metodların yüklənməsi (method overloading) — bu, bir sinifdə eyni adlı, lakin fərqli parametr siyahılarına (növ, say və ya arqumentlərin ardıcıllığı) malik bir neçə metod elan etmək imkanıdır. Belə metodu çağıranda, kompilyator ötürülən arqumentlərə görə hansı versiyadan istifadə etməli olduğunu özü müəyyənləşdirir.
Həyatdan analoq
Təsəvvür edin ki, bankın dəstək xidmətinə zəng edirsiniz. Fərqli nömrələr var — fiziki şəxslər üçün, hüquqi şəxslər üçün, VIP müştərilər üçün. Nömrələr fərqlidir, amma məqsəd eynidir — yardım almaq. Proqramlaşdırmada metodların yüklənməsi elə bir dəstək nömrəsi kimidir ki, sualınızın növündən (yəni ötürdüyünüz parametrlərdən) asılı olaraq sizi avtomatik şəkildə düzgün operatorla birləşdirir.
Java-da overloading-in sintaksisi
Java-da metodların yüklənməsi çox sadə həyata keçirilir: eyni adlı, lakin fərqli parametrlərə malik bir neçə metod elan edirsiniz.
Vacib qayda:
Overloading yalnız parametr siyahısına görə fərqlənir (növ, say, ardıcıllıq).
Yalnız qaytarılan tipə görə overloading-a icazə verilmir!
Metodların adı və parametrləri eynidirsə, qaytarılan tip fərqli olsa belə kompilyator onları ayıra bilməyəcək.
Sadə nümunə
public class Printer {
// Tam ədədin çapı
void print(int x) {
System.out.println("int: " + x);
}
// Sətirin çapı
void print(String s) {
System.out.println("String: " + s);
}
// İki ədədin çapı
void print(int x, int y) {
System.out.println("int, int: " + x + ", " + y);
}
}
İstifadə:
Printer printer = new Printer();
printer.print(42); // print(int x)-i çağıracaq
printer.print("Hello!"); // print(String s)-i çağıracaq
printer.print(5, 10); // print(int x, int y)-i çağıracaq
Kompilyator ötürülən arqumentlərə əsasən hansı metodu çağıracağını özü müəyyən edir.
2. Kompilyator necə lazım olan metodu seçir
Siz yüklənmiş metodu çağıranda, kompilyator arqumentlərin siyahısını analiz edir və ən uyğun versiyanı axtarır.
Seçim meyarları:
- Arqumentlərin sayının uyğunluğu.
- Hər arqumentin tipinin uyğunluğu (və ya tipin çevrilə bilməsi, məsələn, int → double).
- Bir neçə metod uyğun gəlirsə, ən spesifik olan seçilir.
Nümunə:
public class OverloadDemo {
void show(int x) {
System.out.println("show(int): " + x);
}
void show(double x) {
System.out.println("show(double): " + x);
}
public static void main(String[] args) {
OverloadDemo demo = new OverloadDemo();
demo.show(5); // show(int): 5
demo.show(5.5); // show(double): 5.5
}
}
Əgər demo.show(5) çağırsaq, kompilyator show(int) seçəcək. 5.5 ilə çağırsaq — show(double) seçiləcək.
Tip çevrilmələri
Uyğun metod yoxdursa, kompilyator arqument tiplərini çevirməyə çalışacaq (məsələn, int → double), amma yalnız bu mümkün və qeyri-müəyyənlik yaratmadıqda.
void print(double x) { /* ... */ }
print(5); // int 5 double 5.0-a çevrilir
Yalnız qaytarma tipinə görə overloading — işləmir!
Bir çox yeni başlayanlar belə etməyə çalışır:
// Xəta! Belə overload ola bilməz
int sum(int x, int y) { return x + y; }
double sum(int x, int y) { return (double) (x + y); }
Sadəcə sum(2, 3) yazsanız, kompilyator hansı metodu çağırmaq istədiyinizi başa düşməyəcək.
Yadda saxlayın: metodların overloading-i yalnız parametrlərə görə mümkündür, qaytarma tipinə görə deyil!
3. Konstruktorların yüklənməsi
Yalnız adi metodları deyil, konstruktorları da yükləmək olar!
public class Person {
String name;
int age;
// Yalnız ad ilə konstruktor
public Person(String name) {
this.name = name;
this.age = 0; // defolt olaraq
}
// Ad və yaş ilə konstruktor
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
İstifadə:
Person p1 = new Person("Anna");
Person p2 = new Person("Boris", 25);
4. Praktiki nümunələr
Overloading dəstəyi olan Calculator
Gəlin Calculator sinfini yazaq; o, müxtəlif tip və sayda ədədləri toplaya biləcək.
public class Calculator {
// İki tam ədədin cəmi
int add(int a, int b) {
return a + b;
}
// Üç tam ədədin cəmi
int add(int a, int b, int c) {
return a + b + c;
}
// İki double-ın cəmi
double add(double a, double b) {
return a + b;
}
}
İstifadə:
Calculator calc = new Calculator();
System.out.println(calc.add(2, 3)); // 5
System.out.println(calc.add(1, 2, 3)); // 6
System.out.println(calc.add(2.5, 3.1)); // 5.6
Standart kitabxanada metodların overloading-i
Fərqinə varmasanız belə, siz artıq overloading ilə qarşılaşmısınız. Məsələn, System.out-dakı println metodu müxtəlif tiplər üçün yüklənib:
System.out.println("Hello"); // println(String)
System.out.println(123); // println(int)
System.out.println(3.14); // println(double)
System.out.println(true); // println(boolean)
PrintStream sinfinin mənbələrini açın — println-in onlarla yüklənmiş versiyasını görəcəksiniz.
5. Overloading-dən nə vaxt istifadə etməli
Metodların yüklənməsi güclü vasitədir, amma onu ağılla tətbiq etmək lazımdır. O, aşağıdakı hallarda rahatdır:
- Metodun məntiqi eynidir, lakin parametrlər fərqli ola bilər.
- Sinfin API-sini daha dost və çevik etmək istəyirsiniz.
- Metodun köhnə və yeni çağırış variantlarını dəstəkləmək lazımdır.
Həyatdan nümunə:
Tədris tətbiqimizdə (məsələn, tapşırıq menecerində) müxtəlif parametrlərlə tapşırıq əlavə etmək üçün metod reallaşdırmaq olar:
public class TaskManager {
void addTask(String description) { ... }
void addTask(String description, int priority) { ... }
void addTask(String description, int priority, String deadline) { ... }
}
Bu yanaşma təkcə kod istifadəçisi üçün rahat deyil, həm də sinfinizi gələcək dəyişikliklərə qarşı çevik edir.
6. Overloading və varargs (dəyişən sayda arqument)
Java-da ... (varargs) vasitəsilə dəyişən sayda parametrli metod elan etmək mümkündür:
void printAll(String... messages) {
for (String msg : messages) {
System.out.println(msg);
}
}
İndi belə çağırmaq olar:
printAll("Hello");
printAll("One", "Two", "Three");
Varargs ilə overloading də etmək olar, amma ehtiyatlı olun: əgər iki metod varsa və onlardan biri varargs, digəri isə sabit sayda parametr qəbul edirsə, kompilyator əvvəlcə dəqiq uyğunluğu tapmağa çalışacaq.
7. Metodların overloading-ində tipik səhvlər
Səhv №1: Arqument tipləri ilə qarışıqlıq.
Əgər sizdə void process(int x) və void process(double x) metodları varsa, process(5) birincini, process(5.0) isə ikincini çağıracaq. Amma process(5L) çağırılsa, kompilyator ən yaxşı uyğunluğu axtaracaq və qeyri-aşkar bir overload seçə bilər (və ya ümumiyyətlə qeyri-müəyyənlik barədə kompilyasiya xətası verə bilər).
Səhv №2: Avtomatik çevrilmə ilə overloading.
Əgər sizdə void foo(Integer x) və void foo(Long x) varsa, foo(5) çağırışı kompilyasiya xətasına səbəb olacaq — kompilyator hansı metodu seçəcəyini bilmir, çünki 5 həm Integer-ə, həm də Long-a çevrilə bilər.
Səhv №3: Yalnız qaytarma tipinə görə overloading.
Yuxarıda deyildiyi kimi, yalnız qaytarma tipinə görə fərqlənən metodlar yüklənə bilməz.
Səhv №4: Overloading və irsiyyət.
Əgər bazis sinifdə bir metod elan olunubsa və törəmə sinifdə eyni adda, lakin başqa siqnaturlu metod elan edirsinizsə, bu override yox, overloading olacaq. Bu çox vaxt qarışdırılır! Bunun haqqında daha ətraflı — növbəti mühazirədə.
GO TO FULL VERSION