8-bo‘lim
Metodlar
Metod e'lon qilish, static va obyekt metodlari, ortiqcha yuklash, varargs, argumentlarni uzatish qoidasi va rekursiya.
Ushbu bo‘lim mundarijasi
Metod - nom berilgan kod bo'lagi. U bir ishni bajaradi va kerak bo'lganda chaqiriladi.
Oddiy metod #
public class Salomlashuv {
public static void main(String[] args) {
Salomlash("Husanboy");
Salomlash("Malika");
}
static void Salomlash(String ism) {
System.out.println("Assalomu alaykum, " + ism + "!");
}
}
Assalomu alaykum, Husanboy!
Assalomu alaykum, Malika!
Qiymat qaytarish #
public class Hisob {
public static void main(String[] args) {
int natija = Qoshish(7, 5);
System.out.println("7 + 5 = " + natija);
System.out.println("Kvadrat: " + Kvadrat(6));
}
static int Qoshish(int a, int b) {
return a + b;
}
static int Kvadrat(int son) {
return son * son;
}
}
7 + 5 = 12
Kvadrat: 36
void - hech narsa qaytarmaydi. Boshqa har qanday tur - shu turdagi
qiymat qaytariladi va return majburiy.
C# yoki Python'dagi kabi metod ichida metod e'lon qilib bo'lmaydi. Har bir metod sinfga tegishli bo'lishi shart.
Shuning uchun yuqoridagi misollarda yordamchi metodlar main bilan
bir xil sinfda, uning yonida turibdi.
static va obyekt metodlari #
public class Ikki {
private int hisoblagich = 0;
public static void main(String[] args) {
System.out.println("Statik: " + Kvadrat(5));
Ikki obyekt = new Ikki();
obyekt.Oshir();
obyekt.Oshir();
System.out.println("Obyekt hisoblagichi: " + obyekt.Qiymat());
}
static int Kvadrat(int son) {
return son * son;
}
void Oshir() {
hisoblagich++;
}
int Qiymat() {
return hisoblagich;
}
}
Statik: 25
Obyekt hisoblagichi: 2
| Tur | Chaqirish | Qachon |
|---|---|---|
static | Sinf.Metod() | Obyekt holatiga bog'liq emas |
| Oddiy | obyekt.Metod() | Obyekt maydonlari bilan ishlaydi |
main statik, shuning uchun...main metodi static - ya'ni u obyektsiz ishga tushadi. Shu sababli
u faqat boshqa static a'zolarga to'g'ridan-to'g'ri murojaat
qila oladi.
Yangi boshlovchilarning eng ko'p uchraydigan xatosi:
error: non-static method Oshir() cannot be referenced
from a static context
Bu main ichidan oddiy metodni to'g'ridan-to'g'ri chaqirishga
urinilganda chiqadi.
Ikki yechim:
- Yuqoridagi misoldagidek obyekt yarating:
new Ikki().Oshir(); - Metodni ham
staticqiling - agar u obyekt holatiga bog'liq bo'lmasa.
Argumentlar qiymat bo'yicha uzatiladi #
Bu 3-bo'limda ko'rgan qoidaning metodlarga tegishli qismi:
import java.util.Arrays;
public class Uzatish {
public static void main(String[] args) {
int son = 5;
Ozgartir(son);
System.out.println("Primitiv: " + son);
int[] massiv = {1, 2, 3};
IchiniOzgartir(massiv);
System.out.println("Massiv ichi: " + Arrays.toString(massiv));
Almashtir(massiv);
System.out.println("Almashtirgach: " + Arrays.toString(massiv));
}
static void Ozgartir(int x) {
x = 99;
}
static void IchiniOzgartir(int[] m) {
m[0] = 99;
}
static void Almashtir(int[] m) {
m = new int[]{7, 7, 7};
}
}
Primitiv: 5
Massiv ichi: [99, 2, 3]
Almashtirgach: [99, 2, 3]
Uchala holatda ham qiymat nusxalandi:
- primitivda qiymatning o'zi - o'zgarish tashqarida ko'rinmadi;
- massivda havola nusxalandi - obyekt ichini o'zgartirish ko'rindi;
- havolaning o'zini almashtirish esa faqat metod ichida qoldi.
ref yoki out yo'qC# dagi ref va out kabi vositalar Java'da umuman mavjud emas.
Bir nechta qiymat qaytarish kerak bo'lsa uchta yo'l bor:
recordqaytaring (11-bo'lim) - eng toza yechim;- Massiv yoki
Listqaytaring; - Obyekt maydonlarini to'ldiring.
Birinchisi tavsiya etiladi: natija nomlangan bo'ladi va tur tekshiriladi.
Ortiqcha yuklash #
Bir xil nomli, lekin turli parametrli metodlar:
public class Maydon {
public static void main(String[] args) {
System.out.println(Hisobla(5));
System.out.println(Hisobla(4, 6));
System.out.println(Hisobla("kvadrat", 3));
}
static int Hisobla(int tomon) {
return tomon * tomon;
}
static int Hisobla(int eni, int boyi) {
return eni * boyi;
}
static String Hisobla(String nom, int tomon) {
return nom + ": " + (tomon * tomon);
}
}
25
24
kvadrat: 9
Kompilyator argumentlarga qarab qaysi metodni chaqirishni aniqlaydi.
Quyidagi ikki metod bir xil hisoblanadi va kompilyatsiya qilinmaydi:
static int Hisobla(int a) { return a; }
static String Hisobla(int a) { return "" + a; }
error: method Hisobla(int) is already defined
Metodlar parametrlari bilan farqlanishi kerak - turi, soni yoki tartibi bilan. Faqat qaytish turini o'zgartirish yetmaydi.
varargs - istalgancha argument #
public class Yigindi {
public static void main(String[] args) {
System.out.println(Jami());
System.out.println(Jami(5));
System.out.println(Jami(1, 2, 3, 4, 5));
int[] massiv = {10, 20};
System.out.println(Jami(massiv));
}
static int Jami(int... sonlar) {
int natija = 0;
for (int son : sonlar) {
natija += son;
}
return natija;
}
}
0
5
15
30
Uch nuqta (...) "istalgancha argument" degani. Metod ichida u oddiy
massiv bo'ladi, shuning uchun massivni to'g'ridan-to'g'ri uzatish
ham mumkin.
- Metodda faqat bitta varargs parametri bo'lishi mumkin;
- U oxirgi parametr bo'lishi shart.
static void Yoz(String sarlavha, int... sonlar) { } // to'g'ri
static void Yoz(int... sonlar, String sarlavha) { } // XATO
System.out.printf va List.of aynan shu mexanizmdan foydalanadi.
Rekursiya #
Metod o'zini chaqirishi mumkin:
public class Rekursiya {
public static void main(String[] args) {
System.out.println("5! = " + Faktorial(5));
System.out.println("0! = " + Faktorial(0));
StringBuilder qator = new StringBuilder();
for (int i = 0; i < 8; i++) {
if (i > 0) {
qator.append(" ");
}
qator.append(Fibonachchi(i));
}
System.out.println(qator);
}
static long Faktorial(int n) {
if (n < 0) {
throw new IllegalArgumentException("Manfiy son bo'lmasin");
}
return n <= 1 ? 1 : n * Faktorial(n - 1);
}
static int Fibonachchi(int n) {
return n < 2 ? n : Fibonachchi(n - 1) + Fibonachchi(n - 2);
}
}
5! = 120
0! = 1
0 1 1 2 3 5 8 13
Har bir rekursiv metodda bazaviy holat bo'lishi kerak - o'zini chaqirmaydigan tarmoq.
U bo'lmasa yoki unga yetib bo'lmasa, stek to'lib ketadi:
public class Cheksiz {
public static void main(String[] args) {
try {
Ozini(1);
} catch (StackOverflowError x) {
System.out.println("Xato: " + x.getClass().getSimpleName());
}
}
static int Ozini(int n) {
return Ozini(n + 1); // to'xtash sharti yo'q
}
}
Xato: StackOverflowError
Diqqat: bu Exception emas, Error. Odatda Error ni
ushlamaydilar - bu dasturchi xatosi bo'lib, tuzatilishi kerak.
Yuqorida u faqat namoyish uchun ushlangan.
Rekursiya chuqurligi taxminan o'n minglar atrofida cheklangan - aniq son JVM sozlamalariga bog'liq.
Yuqoridagi Fibonachchi chiroyli ko'rinadi, lekin u bir xil
qiymatlarni qayta-qayta hisoblaydi.
Fibonachchi(40) uchun u milliarddan ortiq chaqiruv qiladi va bir
necha soniya ishlaydi. Sikl bilan esa bu bir zumda bajariladi:
public class Tez {
public static void main(String[] args) {
System.out.println("Sikl bilan 40: " + Fib(40));
}
static long Fib(int n) {
long a = 0, b = 1;
for (int i = 0; i < n; i++) {
long keyingi = a + b;
a = b;
b = keyingi;
}
return a;
}
}
Sikl bilan 40: 102334155
Qoida: rekursiya daraxt va ichma-ich tuzilmalar uchun tabiiy, oddiy takrorlash uchun esa sikl afzal.
Metod nomlash qoidalari #
| Qoida | Misol |
|---|---|
| Kichik harfdan boshlanadi (camelCase) | hisoblaYigindi |
| Fe'l bilan boshlanadi | yoz, hisobla, tekshir |
boolean qaytarsa is yoki has | isBosh, hasBaho |
| Sinf nomi katta harfdan (PascalCase) | TalabaJurnali |
Java'da rasmiy an'ana - metodlar kichik harfdan boshlanadi:
hisoblaYigindi.
Bu darslikda o'qish qulayligi uchun metod nomlari katta harfdan
yozilgan (Qoshish, Kvadrat) - shunda ular o'zgaruvchilardan aniq
ajralib turadi.
Haqiqiy Java loyihasida esa camelCase ishlating, aks holda kod boshqa dasturchilarga g'alati ko'rinadi.
- Ikki sondan kattasini qaytaruvchi metod yozing.
maindan oddiy (nostatik) metodni chaqirib, xatoni ko'ring.- Uni ikki xil usulda tuzating.
- Metodga primitiv va massiv uzatib, farqni tekshiring.
- Bir nomli uchta metodni turli parametrlar bilan yozing.
- Faqat qaytish turi bilan farqlanadigan ikki metod yozib, xatoni ko'ring.
varargsbilan istalgancha sonning o'rtachasini hisoblang.- Rekursiv faktorial yozing va manfiy son uchun istisno tashlang.
- To'xtash shartsiz rekursiya yozib,
StackOverflowErrorni ko'ring. - Fibonachchini rekursiv va sikl bilan yozib, 40 uchun vaqtni solishtiring.
Xulosa #
- Java'da lokal funksiya yo'q - har bir metod sinfga tegishli.
staticmetod obyektsiz chaqiriladi;mainham statik, shuning uchun u nostatik a'zolarga to'g'ridan-to'g'ri murojaat qila olmaydi.- Argumentlar har doim qiymat bo'yicha uzatiladi; obyektda nusxalanadigan qiymat - havola.
- Java'da
refvaoutyo'q - bir nechta qiymat uchunrecordqaytaring. - Ortiqcha yuklash parametrlar bilan aniqlanadi; faqat qaytish turi yetarli emas.
varargsoxirgi parametr bo'lishi shart va bittadan ortiq bo'lmaydi.- Rekursiyada bazaviy holat majburiy, aks holda
StackOverflowError. - Oddiy takrorlash uchun sikl, daraxt tuzilmalari uchun rekursiya.
Keyingi bo'limda sinflar va obyektlarga o'tamiz.
O‘qish tarixini saqlamoqchimisiz?
Tizimga kirsangiz, tugatgan bo‘limlaringiz saqlanadi va qoldirgan joyingizdan davom etasiz.
Xatolik topdingizmi?
Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.