← Kursa Dön
📄 Text · 12 min

Constructor (Yapıcı Metotlar)

Giriş

Önceki derste nesne oluşturup field'lara tek tek değer atadık:

Ogrenci ali = new Ogrenci();
ali.isim = "Ali";
ali.yas = 20;
ali.notOrtalamasi = 3.5;

3 satır sadece değer atamak için. 10 field'lı bir sınıfta 10 satır yazacaksın. Hem zahmetli, hem de bir field'ı atamayı unutma ihtimalin var.

Constructor, nesne oluşturulurken otomatik çağrılan özel bir metottur. Amacı: nesneyi doğru başlangıç durumuyla hayata getirmek.

Ogrenci ali = new Ogrenci("Ali", 20, 3.5);  // tek satırda her şey hazır

Constructor Nedir?

Constructor'ı bir fabrika montaj hattı gibi düşün. Araba fabrikasında bir araba üretilirken, montaj hattında motor takılır, boyası yapılır, lastikler monte edilir — araba "kullanıma hazır" halde çıkar. Constructor da nesneyi "kullanıma hazır" hale getirir.

Constructor'ın özellikleri:

  • Adı sınıf adıyla aynı olmalı

  • return tipi yok (void bile yok)

  • new ile nesne oluşturulduğunda otomatik çağrılır

  • Bir sınıfta birden fazla constructor olabilir (overloading)

Default Constructor

Eğer sınıfa hiçbir constructor yazmazsan, Java otomatik olarak parametresiz bir default constructor ekler.

class Ogrenci {
    String isim;
    int yas;
    // Constructor yazmadık — Java default ekler
}

// Bu çalışıyor çünkü default constructor var
Ogrenci o = new Ogrenci();

Default constructor hiçbir şey yapmaz — sadece nesneyi oluşturur ve field'ları varsayılan değerlerle bırakır.

⚠️ Dikkat: Eğer herhangi bir constructor yazarsan, Java artık default constructor eklemez. Bu çok önemli!

class Ogrenci {
    String isim;
    int yas;

    // Parametreli constructor yazdık
    Ogrenci(String isim, int yas) {
        this.isim = isim;
        this.yas = yas;
    }
}

Ogrenci o1 = new Ogrenci("Ali", 20);  // çalışır
Ogrenci o2 = new Ogrenci();           // DERLEME HATASI! Default constructor yok artık

Default constructor'ı da kullanmak istiyorsan, açıkça yazmalısın.

Parametreli Constructor

En yaygın constructor türü. Nesneyi oluştururken gerekli verileri parametre olarak alır.

class Ogrenci {
    String isim;
    int yas;
    double notOrtalamasi;

    Ogrenci(String isim, int yas, double notOrtalamasi) {
        this.isim = isim;
        this.yas = yas;
        this.notOrtalamasi = notOrtalamasi;
    }

    void bilgiGoster() {
        System.out.println(isim + " (" + yas + ") - GPA: " + notOrtalamasi);
    }
}

// Kullanım
Ogrenci ali = new Ogrenci("Ali", 20, 3.5);
Ogrenci ayse = new Ogrenci("Ayse", 22, 3.8);

ali.bilgiGoster();   // Ali (20) - GPA: 3.5
ayse.bilgiGoster();  // Ayse (22) - GPA: 3.8

Artık nesne oluşturulduktan sonra eksik field kalmıyor. Constructor, nesnenin geçerli bir durumda başlamasını garanti eder.

Constructor İçinde Doğrulama

Constructor'da parametre kontrolü yapabilirsin:

class BankaHesabi {
    String sahibi;
    double bakiye;

    BankaHesabi(String sahibi, double baslangicBakiye) {
        if (sahibi == null || sahibi.isEmpty()) {
            throw new IllegalArgumentException("Hesap sahibi boş olamaz!");
        }
        if (baslangicBakiye < 0) {
            throw new IllegalArgumentException("Başlangıç bakiyesi negatif olamaz!");
        }
        this.sahibi = sahibi;
        this.bakiye = baslangicBakiye;
    }
}

Bu şekilde "geçersiz" bir nesne oluşturulmasını önlersin. Constructor, nesnenin kapısındaki güvenlik görevlisi gibi.

Constructor Overloading (Aşırı Yükleme)

Bir sınıfta birden fazla constructor olabilir — farklı parametre listeleriyle.

class Ogrenci {
    String isim;
    int yas;
    double notOrtalamasi;

    // Constructor 1: Tüm parametreler
    Ogrenci(String isim, int yas, double notOrtalamasi) {
        this.isim = isim;
        this.yas = yas;
        this.notOrtalamasi = notOrtalamasi;
    }

    // Constructor 2: Not yok (varsayılan 0.0)
    Ogrenci(String isim, int yas) {
        this.isim = isim;
        this.yas = yas;
        this.notOrtalamasi = 0.0;
    }

    // Constructor 3: Sadece isim
    Ogrenci(String isim) {
        this.isim = isim;
        this.yas = 18;
        this.notOrtalamasi = 0.0;
    }

    // Constructor 4: Parametresiz
    Ogrenci() {
        this.isim = "Bilinmiyor";
        this.yas = 0;
        this.notOrtalamasi = 0.0;
    }
}

// Hepsi geçerli
Ogrenci o1 = new Ogrenci("Ali", 20, 3.5);
Ogrenci o2 = new Ogrenci("Ayse", 22);
Ogrenci o3 = new Ogrenci("Mehmet");
Ogrenci o4 = new Ogrenci();

Java, verdiğin parametrelere göre hangi constructor'ı çağıracağını otomatik belirler.

Constructor Chaining — this()

Overloaded constructor'larda çok fazla kod tekrarı olabilir. this() ile bir constructor'dan diğerini çağırabilirsin.

class Ogrenci {
    String isim;
    int yas;
    double notOrtalamasi;

    // Ana constructor
    Ogrenci(String isim, int yas, double notOrtalamasi) {
        this.isim = isim;
        this.yas = yas;
        this.notOrtalamasi = notOrtalamasi;
    }

    // this() ile ana constructor'ı çağır
    Ogrenci(String isim, int yas) {
        this(isim, yas, 0.0);  // 3 parametreli constructor'ı çağır
    }

    Ogrenci(String isim) {
        this(isim, 18);  // 2 parametreli constructor'ı çağır
    }

    Ogrenci() {
        this("Bilinmiyor");  // 1 parametreli constructor'ı çağır
    }
}

Bu zincirleme yapıda her constructor bir üsttekini çağırıyor. Gerçek atama işlemi sadece ana constructor'da yapılıyor — kod tekrarı sıfır.

this() Kuralları

  • this() çağrısı constructor'ın ilk satırında olmalı

  • Bir constructor'da sadece bir this() çağrısı olabilir

  • Döngüsel çağrı yapılamaz (A → B → A → ∞)

// DERLEME HATASI — this() ilk satırda olmalı
Ogrenci(String isim) {
    System.out.println("Oluşturuluyor...");
    this(isim, 18);  // HATA! İlk satır değil
}

// DOĞRU
Ogrenci(String isim) {
    this(isim, 18);  // ilk satır
    System.out.println("Oluşturuldu.");
}

💡 İpucu: Constructor chaining, "telescoping constructor" pattern olarak da bilinir. En az parametreli constructor en çok parametreli olanı çağırır. Kod tekrarını önlemenin en temiz yolu.

Copy Constructor (Kopyalama Constructor'ı)

Mevcut bir nesnenin kopyasını oluşturmak için kullanılır.

class Ogrenci {
    String isim;
    int yas;
    double notOrtalamasi;

    // Normal constructor
    Ogrenci(String isim, int yas, double notOrtalamasi) {
        this.isim = isim;
        this.yas = yas;
        this.notOrtalamasi = notOrtalamasi;
    }

    // Copy constructor
    Ogrenci(Ogrenci diger) {
        this.isim = diger.isim;
        this.yas = diger.yas;
        this.notOrtalamasi = diger.notOrtalamasi;
    }
}

// Kullanım
Ogrenci ali = new Ogrenci("Ali", 20, 3.5);
Ogrenci aliKopya = new Ogrenci(ali);  // ali'nin kopyası

aliKopya.isim = "Ali Kopya";
System.out.println(ali.isim);       // Ali — orijinal değişmedi
System.out.println(aliKopya.isim);  // Ali Kopya

= ile atama referans kopyalar (aynı nesne, iki isim). Copy constructor ise yeni nesne oluşturur. Önceki derste öğrendiğimiz referans sorununu çözer.

⚠️ Dikkat: Copy constructor'da referans tipli field'lar varsa dikkatli ol. String immutable olduğu için sorun yok, ama mutable nesneler (ArrayList, diğer sınıflar) durumunda deep copy yapman gerekir.

class Sinif {
    String ad;
    ArrayList<String> ogrenciler;

    Sinif(Sinif diger) {
        this.ad = diger.ad;
        // Shallow copy — tehlikeli!
        // this.ogrenciler = diger.ogrenciler;

        // Deep copy — güvenli
        this.ogrenciler = new ArrayList<>(diger.ogrenciler);
    }
}

Pratik Örnek: Dikdörtgen Sınıfı

class Dikdortgen {
    double en;
    double boy;

    // Tam parametre
    Dikdortgen(double en, double boy) {
        this.en = en;
        this.boy = boy;
    }

    // Kare (en = boy)
    Dikdortgen(double kenar) {
        this(kenar, kenar);
    }

    // Birim kare
    Dikdortgen() {
        this(1.0);
    }

    // Copy
    Dikdortgen(Dikdortgen diger) {
        this(diger.en, diger.boy);
    }

    double alan() {
        return en * boy;
    }

    double cevre() {
        return 2 * (en + boy);
    }

    void bilgi() {
        System.out.printf("%.1f x %.1f | Alan: %.1f | Çevre: %.1f%n",
            en, boy, alan(), cevre());
    }
}

public class Main {
    public static void main(String[] args) {
        Dikdortgen d1 = new Dikdortgen(5, 3);
        Dikdortgen kare = new Dikdortgen(4);
        Dikdortgen birim = new Dikdortgen();
        Dikdortgen kopya = new Dikdortgen(d1);

        d1.bilgi();    // 5.0 x 3.0 | Alan: 15.0 | Çevre: 16.0
        kare.bilgi();  // 4.0 x 4.0 | Alan: 16.0 | Çevre: 16.0
        birim.bilgi(); // 1.0 x 1.0 | Alan: 1.0 | Çevre: 4.0
        kopya.bilgi(); // 5.0 x 3.0 | Alan: 15.0 | Çevre: 16.0
    }
}

4 farklı constructor, her biri farklı bir senaryo için. Constructor chaining ile kod tekrarı sıfır.

Constructor vs Metot

ÖzellikConstructorMetot
İsimSınıf adıyla aynıHerhangi bir isim
Return tipiYokVar (void dahil)
Ne zaman çağrılırnew ile otomatikManuel olarak
Kaç kez çağrılırNesne başına 1 kezİstenildiği kadar
AmacıNesneyi başlatmakİş yapmak
class Ornek {
    Ornek() { }         // constructor — return tipi YOK
    void Ornek() { }    // metot — return tipi var (void), CONSTRUCTOR DEĞİL!
}

İsimleri aynı olsa bile void yazarsan metot olur, constructor olmaz. Bu hata yapılabilir, dikkat et.

Yaygın Hatalar

Hata 1: Constructor'a return tipi yazmak

class Ogrenci {
    void Ogrenci(String isim) { }  // Bu CONSTRUCTOR değil, metot!
}

Hata 2: this()'i ilk satıra yazmamak

Ogrenci(String isim) {
    this.isim = isim;
    this(isim, 18);  // HATA! this() ilk satırda olmalı
}

Hata 3: Default constructor'ın kaybolması

class Ogrenci {
    Ogrenci(String isim) { this.isim = isim; }
}
Ogrenci o = new Ogrenci();  // HATA! Default constructor yok artık

Özet

  • Constructor nesne oluşturulurken çağrılan, sınıf adıyla aynı isimli, return tipi olmayan özel metottur

  • Hiçbir constructor yazmazsan Java default constructor ekler; herhangi birini yazarsan default gider

  • Overloading ile farklı parametre listelerine sahip birden fazla constructor yazılabilir

  • this() ile bir constructor başka bir constructor'ı çağırabilir (chaining) — ilk satırda olmalı

  • Copy constructor mevcut nesnenin bağımsız kopyasını oluşturur

  • Constructor'ın amacı nesneyi geçerli başlangıç durumuyla hayata getirmektir