Metotlar: parametre, return, scope, overloading, Math ve Random
Metot başlığı, parametre ve argüman, return ile void, pass-by-value, kapsam (scope), aşırı yükleme (overloading), Math sınıfı ve rastgele sayı aralıkları. Vizedeki 'write a method' sorularının temeli.
Metot (method), bir işi yapan ve ismi olan bir kod bloğudur. Aynı işi on yerde yazmak yerine bir kez yazar, istediğin yerden çağırırsın. Vizede iki taraftan gelir: “bu çağrılar ne basar?” (içten dışa izleme, pass-by-value) ve “şu işi yapan bir metot yaz” (isPrime, sumDigits, max). İkincisinde başlığı doğru yazmak tek başına puan getirir.
Altın kurallar:
- Başlık şablonu:
public static <dönüş tipi> <ad>(<parametreler>). - void değilse her yolda return olmalı ve dönen değer tipe uymalı.
- return metodu anında bitirir.
- Pass-by-value: metot, çağıranın değişkenini değiştiremez.
- Overloading = aynı ad, farklı parametre listesi. Dönüş tipi tek başına yetmez.
Metot anatomisi
public static double average(int a, int b) {
return (a + b) / 2.0;
}
| Parça | Bu örnekte | Anlamı |
|---|---|---|
| erişim (access modifier) | public | her yerden çağrılabilir |
static | static | nesne oluşturmadan, doğrudan çağrılır (main de static) |
| dönüş tipi (return type) | double | metodun geri verdiği değerin tipi; hiçbir şey vermiyorsa void |
| ad | average | küçük harfle başlar, fiil gibi: computeTotal, isEven |
| parametre listesi | (int a, int b) | metodun dışarıdan aldığı değerler |
| gövde | { return ...; } | işin yapıldığı yer |
Parametre (parameter) başlıktaki değişkendir: a, b. Argüman (argument) çağrı sırasında verilen gerçek değerdir: average(3, 4) çağrısında 3 ve 4. Argümanların sayısı, sırası ve tipi parametrelerle uyuşmalı.
Bu derste metotlar main ile aynı sınıfa yazılır ve main’den çağrıldığı için static olur. Bir metodu tanımlamak onu çalıştırmaz; sadece çağrıldığında (call) çalışır.
return ve void
public static int twice(int n) { return n * 2; }
public static void greet(String name) { System.out.println("Hi " + name); }
public static int max(int a, int b) {
if (a > b) return a;
return b;
}
public static void line(int n, char c) {
for (int i = 0; i < n; i++) System.out.print(c);
System.out.println();
}
// main içinde:
System.out.println(twice(4));
greet("Deniz");
int t = twice(twice(3)); // içten dışa: twice(3) = 6, twice(6) = 12
System.out.println(t);
System.out.println(average(3, 4));
System.out.println(max(8, 11) + " " + max(5, 5));
line(5, '=');
8
Hi Deniz
12
3.5
11 5
=====
- Değer döndüren metot bir ifadenin içinde kullanılır: yazdırılır, bir değişkene atanır ya da başka bir çağrıya argüman olur.
- void metot bir iş yapar (yazdırmak gibi) ve hiçbir şey döndürmez.
System.out.println(greet("x"))derlenmez.
Derleyicinin yakaladığı return hataları
static int f(int a) { return 2.5; } // double, int'e sığmaz
static void g() { return 5; } // void değer döndüremez
static int h(int a) { if (a > 0) return 1; } // a <= 0 iken return yok
Ret.java:2: error: incompatible types: possible lossy conversion from double to int
Ret.java:3: error: incompatible types: unexpected return value
Miss.java:2: error: missing return statement
missing return statement hatası şunu söyler: derleyici, koşul false olduğunda metodun ne döndüreceğini bilemiyor. Her olası yolun sonunda bir return olmalı.
Çağrı izleme ve pass-by-value
Bir metot çağrıldığında Java:
- Argümanları hesaplar.
- Değerlerini parametrelere kopyalar.
- Metodun gövdesini çalıştırır.
- return görünce değeri çağrının yapıldığı yere geri götürür.
public static void change(int x) {
x = 100;
System.out.println("inside: " + x);
}
// main içinde:
int a = 3;
change(a);
System.out.println("outside: " + a);
inside: 100
outside: 3
change’e a’nın kendisi değil, değeri (3) gitti. x = 100 sadece metodun kendi kopyasını değiştirdi. Buna pass-by-value denir ve Java’da her şey böyle geçer. (Dizilerde ve nesnelerde bu kuralın ilginç bir sonucu var; 6. ve 13. haftalarda göreceksin.)
Kapsam (scope)
Bir değişken sadece tanımlandığı blok { } içinde yaşar.
- Metodun içinde tanımlanan değişken (local variable) başka metotta görünmez.
- Parametreler de yereldir; metot bitince yok olur.
- for başlığında tanımlanan sayaç döngüden sonra yoktur.
static void a() { int secret = 5; }
static void b() { System.out.println(secret); }
LocalScope.java:3: error: cannot find symbol
Farklı metotlarda aynı isimli değişkenler olabilir (main’de n, counter’da n); birbirleriyle ilgisizdirler.
Method overloading (aşırı yükleme)
Aynı sınıfta aynı isimde birden çok metot olabilir, yeter ki parametre listeleri (sayı, tip ya da sıra) farklı olsun. Metot adı ile parametre tiplerinin birleşimine imza (signature) denir.
static int add(int a, int b) { return a + b; }
static double add(double a, double b) { return a + b; }
static int add(int a, int b, int c) { return a + b + c; }
// main içinde:
System.out.println(add(2, 3)); // int, int
System.out.println(add(2.0, 3)); // double, int → 3 genişler → add(double, double)
System.out.println(add(1, 2, 3)); // üç argüman
5
5.0
6
Seçim kuralı: önce tam eşleşme aranır. Yoksa Java argümanı genişletebileceği en yakın tipe gider (int → long → float → double). Daraltma asla otomatik yapılmaz.
TUZAK · sadece dönüş tipi farklı.
static int k(int a)vestatic double k(int b)birlikte derlenmez:method k(int) is already defined. Parametre adı ve dönüş tipi imzaya dahil değildir.
Math sınıfı
Math’in metotları static’tir: Math.ad(...) diye çağrılır, import gerekmez.
System.out.println(Math.pow(3, 2));
System.out.println(Math.sqrt(16));
System.out.println(Math.max(4, 9) + " " + Math.min(4, 9));
System.out.println(Math.max(4, 9.0));
System.out.println(Math.abs(-3.5) + " " + Math.abs(-7));
System.out.println(Math.round(3.49) + " " + Math.round(3.5) + " " + Math.round(-2.5));
System.out.println(Math.ceil(2.1) + " " + Math.floor(2.9) + " " + Math.ceil(-2.1));
System.out.println(Math.PI);
9.0
4.0
9 4
9.0
3.5 7
3 4 -2
3.0 2.0 -2.0
3.141592653589793
| Metot | Ne yapar | Dönüş tipi |
|---|---|---|
Math.pow(a, b) | a üzeri b | her zaman double |
Math.sqrt(x) | karekök | double |
Math.abs(x) | mutlak değer | argümanın tipi |
Math.max(a, b), Math.min(a, b) | büyük, küçük | argümanların tipi (biri double ise double) |
Math.round(x) | en yakın tam sayı, .5 yukarı | long (double argümanla) |
Math.ceil(x) | yukarı yuvarla | double |
Math.floor(x) | aşağı yuvarla | double |
TUZAK ·
Math.pow(2, 3)= 8 değil 8.0. Çıktı sorularında double dönen metotların.0ile basıldığını unutma.
Math.round(-2.5) sonucu -2: “.5 yukarı” kuralı sayı doğrusunda yukarı, yani büyük olana doğru demek.
Rastgele sayılar
İki yol var:
import java.util.Random;
Random rand = new Random();
int die = rand.nextInt(6) + 1; // 1..6
int r = rand.nextInt(11) + 10; // 10..20
int m = (int) (Math.random() * 100) + 1; // 1..100
Her ifade bir milyon kez çalıştırılınca görülen en küçük ve en büyük değerler:
1..6 10..20 1..100
Formül: min..max için rand.nextInt(max - min + 1) + min. nextInt(k) 0’dan k-1’e kadar k farklı değer üretir; + min aralığı kaydırır.
Math.random() 0.0 ile 1.0 arasında (1.0 hariç) bir double verir. Çarp, cast et, kaydır. Parantezin yeri kritik: (int) Math.random() * 100 her zaman 0’dır, çünkü cast çarpmadan önce yapılır.
Çözümlü örnek: yazma sorusu nasıl puan toplar
“isPrime yaz” gibi bir soruda kısmi puan şu sırayla gelir:
- Başlık:
public static boolean isPrime(int n). Cevap evet/hayır ise dönüş tipi boolean. - Özel durum:
if (n < 2) return false; - Döngü ve koşul:
for (int i = 2; i * i <= n; i++) if (n % i == 0) return false; - Döngüden sonra:
return true; - Kâğıt üstünde bir örnekle test: 9 için i = 2 (kalan 1), i = 3 (kalan 0) → false. Doğru.
TUZAK · return true’yu else’e koymak.
if (n % i == 0) return false; else return true;yazarsan döngü ilk turda biter, sadece 2’ye bölünmeyi kontrol etmiş olursun. 9’a “asal” der.
Sık yapılan hatalar
| Yanlış düşünce | Doğrusu |
|---|---|
| Metodu tanımlamak onu çalıştırır | Sadece çağrılınca çalışır |
| Dönen değer otomatik bir yere yazılır | Atamazsan ya da yazdırmazsan kaybolur |
| Metot içinde parametreyi değiştirmek main’i değiştirir | Pass-by-value, kopya değişir |
return sonrası satırlar da çalışır | Metot orada biter |
void metottan return x; | Sadece return; olabilir |
| Sadece dönüş tipi farklı iki metot = overloading | Derlenmez |
Math.sqrt(16) → 4 | 4.0 |
Math.round(2.5) → 2 | 3 |
Zar için rand.nextInt(6) | 0..5 verir; + 1 ekle |
(int) Math.random() * 6 + 1 zar | Hep 1; (int) (Math.random() * 6) + 1 yaz |
| Başka metodun değişkenine erişmek | Yerel değişken sadece kendi bloğunda |
Kendini test et
Sınavdaki gibi İngilizce sorular. Önce kâğıt kalemle çöz, sonra cevabı aç.
What is printed?
static int f(int x) { return x + 3; }
static int g(int x) { return f(x) * 2; }
// in main:
System.out.println(g(4));Cevabı göster
g(4) önce f(4)'ü çağırır: 4 + 3 = 7. g'ye dönülür: 7 * 2 = 14. İçteki çağrı her zaman önce biter.
What is printed?
static int mystery(int n) {
int r = 0;
for (int i = 1; i <= n; i++) {
if (i % 2 == 1) r += i;
}
return r;
}
// in main:
System.out.println(mystery(6));Cevabı göster
1'den 6'ya kadar tek sayıları toplar: 1 + 3 + 5 = 9.
What is printed?
static void swap(int a, int b) {
int t = a; a = b; b = t;
System.out.println("in swap: " + a + " " + b);
}
// in main:
int x = 5, y = 9;
swap(x, y);
System.out.println("in main: " + x + " " + y);Cevabı göster
in main: 5 9
Java pass-by-value çalışır: metoda x ve y'nin kopyaları gider. swap kendi kopyalarını değiştirir (9 5 basar) ama main'deki x ve y'ye dokunamaz.
What is printed?
static int early(int n) {
if (n > 5) return 1;
System.out.println("small");
return 0;
}
// in main:
System.out.println(early(8));
System.out.println(early(2));Cevabı göster
small
0
early(8): 8 > 5 → return 1, metot anında biter, small basılmaz. early(2): koşul false, small basılır, sonra 0 döner ve main onu basar.
What is printed?
static int counter(int n) {
n++;
return n;
}
// in main:
int n = 10;
n = counter(n);
counter(n);
System.out.println(n);Cevabı göster
İlk çağrının sonucu (11) n'ye atanır. İkinci çağrı 12 döndürür ama sonuç hiçbir yere atanmadığı için kaybolur. main'deki n 11 kalır.
What is printed?
static void show(int x) { System.out.println("int: " + x); }
static void show(double x) { System.out.println("double: " + x); }
static void show(String s) { System.out.println("String: " + s); }
// in main:
show(7 / 2);
show(7 / 2.0);
show("" + 7 / 2);Cevabı göster
double: 3.5
String: 3
Önce argüman hesaplanır, sonra tipine göre metot seçilir. 7 / 2 = 3 (int) → show(int). 7 / 2.0 = 3.5 (double) → show(double). "" + 7 / 2: önce bölme (3), sonra birleştirme → "3" String → show(String).
Only these two overloads exist. What is printed?
static void p(double d) { System.out.println("double " + d); }
static void p(long l) { System.out.println("long " + l); }
// in main:
p(5);
p(5.0f);Cevabı göster
double 5.0
p(int) yok. Java int argümanı genişletebileceği (widening) en yakın tipe gönderir: int → long, double'dan önce gelir. 5.0f bir float; long'a gidemez (daraltma), double'a genişler.
What is printed?
System.out.println(Math.pow(2, 3) + Math.max(2, 3));
System.out.println(Math.sqrt(25) + " " + Math.abs(-4) + " " + Math.round(2.5));
System.out.println(Math.ceil(4.1) + " " + Math.floor(4.9) + " " + (int) Math.ceil(4.1));Cevabı göster
5.0 4 3
5.0 4.0 5
pow her zaman double döner: 8.0 + 3 = 11.0. sqrt da double: 5.0. abs ve max argümanın tipini korur: 4. round(2.5) en yakın tam sayı, .5 yukarı: 3. ceil/floor double döner: 5.0, 4.0. Cast ile int'e çevrilince 5.
What is printed?
static int square(int x) { return x * x; }
static int twice(int n) { return n * 2; }
static int max(int a, int b) { if (a > b) return a; return b; }
// in main:
System.out.println(square(square(2)) + square(3));
System.out.println(max(square(3), twice(5)));Cevabı göster
10
square(2) = 4, square(4) = 16, square(3) = 9, 16 + 9 = 25. İkinci satır: max(9, 10) = 10.
Assume Random rand = new Random();. Which values can each expression produce? (a) rand.nextInt(6) + 1 (b) rand.nextInt(5) + 3 (c) (int) (Math.random() * 10) (d) (int) Math.random() * 10
Cevabı göster
nextInt(k) 0 ile k-1 arası verir. (a) 0..5 + 1. (b) 0..4 + 3. (c) Math.random() 0.0 ≤ x < 1.0, × 10 → 0.0..9.99, cast → 0..9. (d) Cast önce Math.random()'a uygulanır: (int) 0.73 = 0, 0 * 10 = 0. Doğrulamada 1000 denemenin toplamı 0 çıktı.
Write a static method isPrime(int n) that returns true if n is prime. Numbers less than 2 are not prime.
Cevabı göster
Bölen ararsın; bir tane bulmak yeter. return true döngünün dışında olmalı: ancak hiç bölen bulunmazsa çalışır.public static boolean isPrime(int n) { if (n < 2) return false; for (int i = 2; i * i <= n; i++) { if (n % i == 0) return false; } return true;}1..30 arası asallar: 2 3 5 7 11 13 17 19 23 29. isPrime(49) → false, isPrime(97) → true. i * i <= n yerine i < n yazmak da doğrudur, sadece daha yavaş.
Write a static method sumDigits(int n) that returns the sum of the digits of a non-negative integer, using a while loop. Example: sumDigits(4823) returns 17.
Cevabı göster
% 10 son basamağı verir, / 10 siler. n 0 olunca basamak kalmamıştır.public static int sumDigits(int n) { int sum = 0; while (n > 0) { sum += n % 10; n /= 10; } return sum;}Test: 4823 → 17, 309 → 12, 7 → 7, 0 → 0 (döngüye hiç girilmez).
Doğrulama: Tüm çıktılar JDK 26 ile çalıştırıldı (verify/SEN1001/W05.java). Random aralıkları 1.000.000 denemeyle gözlendi (min..max). Derleme hataları verify/SEN1001/err/Ret.java, Miss.java ve LocalScope.java javac ile alındı.