← Kursa Dön
📄 Text · 15 min

Sınıf ve Nesne Kavramı

Giriş

Önceki derste OOP'un ne olduğunu, sınıf ve nesne kavramlarını tanıdık. Bu derste ellerimizi kirletiyoruz: sınıf nasıl tanımlanır, nesne nasıl oluşturulur, field ve metotlar nasıl çalışır — hepsini detaylıca göreceğiz.

Sınıf Tanımlama

Sınıf tanımlamak için class anahtar kelimesini kullanırsın:

class Ogrenci {
    // field'lar (özellikler)
    String isim;
    int yas;
    double notOrtalamasi;

    // metotlar (davranışlar)
    void selamVer() {
        System.out.println("Merhaba, ben " + isim + "!");
    }
}

Bu kadar. Ogrenci adında bir sınıf tanımladık. İçinde 3 field ve 1 metot var.

Dosya Kuralları

  • Bir .java dosyasında birden fazla sınıf olabilir ama sadece biri public olabilir

  • public sınıfın adı dosya adıyla aynı olmalı: Ogrenci.javapublic class Ogrenci

  • Convention: her sınıf kendi dosyasında olsun (best practice)

// Ogrenci.java
public class Ogrenci {
    String isim;
    int yas;
}

// Aynı dosyada (ama public değil)
class YardimciSinif {
    // ...
}

Field'lar (Alanlar)

Field'lar nesnenin özelliklerini tutar. Sınıf içinde, metot dışında tanımlanır.

class Araba {
    String marka;         // referans tip
    String model;
    int yil;              // primitive tip
    double motorHacmi;
    boolean calisiyor;
}

Field Varsayılan Değerleri

Field'lara değer atamazsan, Java varsayılan değer verir (tıpkı dizilerdeki gibi):

Araba a = new Araba();
System.out.println(a.marka);       // null
System.out.println(a.yil);         // 0
System.out.println(a.motorHacmi);  // 0.0
System.out.println(a.calisiyor);   // false

Bu, lokal değişkenlerden farklıdır. Lokal değişkenlere değer atamadan kullanamazsın (derleme hatası), ama field'lar varsayılan değer alır.

Field vs Lokal Değişken

ÖzellikFieldLokal Değişken
Tanım yeriSınıf içinde, metot dışındaMetot içinde
Varsayılan değerVar (0, null, false, vs.)Yok (atanmadan kullanılamaz)
ErişimSınıfın tüm metotlarındanSadece tanımlandığı metot/blok
Yaşam süresiNesne yaşadığı süreceMetot/blok bitince

Metotlar (Davranışlar)

Metotlar nesnenin ne yapabileceğini tanımlar.

class Hesap {
    double bakiye;

    void paraYatir(double miktar) {
        bakiye += miktar;
        System.out.println(miktar + " TL yatırıldı. Bakiye: " + bakiye);
    }

    void paraCek(double miktar) {
        if (miktar <= bakiye) {
            bakiye -= miktar;
            System.out.println(miktar + " TL çekildi. Bakiye: " + bakiye);
        } else {
            System.out.println("Yetersiz bakiye!");
        }
    }

    double getBakiye() {
        return bakiye;
    }
}

Metotlar field'lara doğrudan erişebilir. bakiye += miktar yazabiliyorsun çünkü bakiye o sınıfın field'ı.

new Keyword — Nesne Oluşturma

Sınıf bir şablon. Nesne oluşturmak için new anahtar kelimesini kullanırsın.

Ogrenci ali = new Ogrenci();

Bu satırda 3 şey oluyor:

  1. Ogrenci aliali adında bir referans değişkeni tanımlanır

  2. new Ogrenci() → Bellekte (heap) yeni bir Ogrenci nesnesi oluşturulur

  3. = → Referans değişkeni, bellekteki nesneyi gösterir (işaret eder)

Bunu bir adres gibi düşün. ali değişkeni nesnenin kendisi değil, nesnenin adresidir. Tıpkı bir evin adresi o evin kendisi olmadığı gibi.

Ogrenci ali = new Ogrenci();
ali.isim = "Ali";
ali.yas = 20;
ali.selamVer();  // Merhaba, ben Ali!

Ogrenci ayse = new Ogrenci();
ayse.isim = "Ayse";
ayse.yas = 22;
ayse.selamVer();  // Merhaba, ben Ayse!

Her new çağrısı bellekte ayrı bir nesne oluşturur. ali ve ayse birbirinden bağımsız.

Nokta (.) Operatörü

Nesnenin field ve metotlarına nokta operatörü ile erişirsin:

ali.isim = "Ali";     // field'a değer atama
String ad = ali.isim; // field'dan okuma
ali.selamVer();        // metot çağırma

nesne.field ve nesne.metot() — bu pattern'i her yerde göreceksin.

this Keyword

this, o anki nesneyi referans eden özel bir anahtar kelimedir. En yaygın kullanımı: parametre adı ile field adı aynı olduğunda.

class Ogrenci {
    String isim;
    int yas;

    void bilgiAta(String isim, int yas) {
        this.isim = isim;   // this.isim = field, isim = parametre
        this.yas = yas;
    }
}

this olmadan Java hangisinin field, hangisinin parametre olduğunu bilemez. isim = isim yazarsan, parametreyi kendisine atamış olursun — field değişmez.

// YANLIŞ — field değişmez
void bilgiAta(String isim, int yas) {
    isim = isim;   // parametre = parametre (field'a dokunulmadı)
    yas = yas;
}

// DOĞRU — field değişir
void bilgiAta(String isim, int yas) {
    this.isim = isim;   // field = parametre
    this.yas = yas;
}

this'in Diğer Kullanımları

class Ogrenci {
    String isim;

    // Mevcut nesneyi döndürme (method chaining için)
    Ogrenci isimAta(String isim) {
        this.isim = isim;
        return this;  // kendini döndür
    }

    // Mevcut nesneyi parametre olarak geçirme
    void kaydet() {
        VeriTabani.ekle(this);  // kendini gönder
    }
}

💡 İpucu: this her zaman yazmak zorunda değilsin. Sadece parametre adı ile field adı çakıştığında gerekli. Ama bazı geliştiriciler okunabilirlik için her zaman yazarlar.

Nesne Referansı

Java'da nesneler referans ile tutulur. Değişken nesnenin kendisini değil, bellekteki adresini tutar.

Ogrenci a = new Ogrenci();
a.isim = "Ali";

Ogrenci b = a;  // KOPYA DEĞİL! Aynı nesneye ikinci referans.

b.isim = "Veli";

System.out.println(a.isim);  // "Veli" — a da değişti!

b = a dediğinde yeni nesne oluşmadı. b, a'nın gösterdiği aynı nesneyi göstermeye başladı. İkisi de aynı nesneye işaret ediyor — birinden değiştirdiğinde diğerinden de görünüyor.

Referans Karşılaştırma

Ogrenci x = new Ogrenci();
x.isim = "Ali";

Ogrenci y = new Ogrenci();
y.isim = "Ali";

Ogrenci z = x;

System.out.println(x == y);   // false — farklı nesneler
System.out.println(x == z);   // true — aynı nesne

== operatörü nesnelerde referansları karşılaştırır (aynı nesne mi?), içerikleri değil. İçerik karşılaştırması için equals() metodunu override etmek gerekir (ileride göreceğiz).

null

null, "hiçbir nesneye işaret etmiyor" demektir. Bir referans değişkeni null olabilir.

Ogrenci o = null;  // o hiçbir nesneyi göstermiyor

System.out.println(o);       // null
System.out.println(o.isim);  // NullPointerException!

null bir nesne üzerinde metot veya field erişimi yapmaya çalışırsan Java NullPointerException (NPE) fırlatır. Bu, Java'daki en sık karşılaşılan hatalardan biridir.

null Kontrolü

Ogrenci o = getOgrenci();  // null dönebilir

if (o != null) {
    System.out.println(o.isim);
} else {
    System.out.println("Öğrenci bulunamadı");
}

⚠️ Dikkat: Bir nesneyi kullanmadan önce null olup olmadığını kontrol et. Özellikle metottan dönen değerler null olabilir.

Birden Fazla Nesne ile Çalışma

class Urun {
    String ad;
    double fiyat;

    void bilgiGoster() {
        System.out.println(ad + " - " + fiyat + " TL");
    }
}

public class Main {
    public static void main(String[] args) {
        // Dizi ile birden fazla nesne
        Urun[] urunler = new Urun[3];

        urunler[0] = new Urun();
        urunler[0].ad = "Laptop";
        urunler[0].fiyat = 25000;

        urunler[1] = new Urun();
        urunler[1].ad = "Telefon";
        urunler[1].fiyat = 15000;

        urunler[2] = new Urun();
        urunler[2].ad = "Tablet";
        urunler[2].fiyat = 10000;

        // Tüm ürünleri göster
        for (Urun u : urunler) {
            u.bilgiGoster();
        }
    }
}

Nesne dizisi oluştururken dikkat: new Urun[3] sadece referans dizisi oluşturur, nesneleri oluşturmaz! Her eleman başta null'dır. Her birine ayrıca new Urun() demen gerekir.

ArrayList ile Nesneler

ArrayList<Urun> urunler = new ArrayList<>();

Urun laptop = new Urun();
laptop.ad = "Laptop";
laptop.fiyat = 25000;
urunler.add(laptop);

Urun telefon = new Urun();
telefon.ad = "Telefon";
telefon.fiyat = 15000;
urunler.add(telefon);

for (Urun u : urunler) {
    u.bilgiGoster();
}

Metotlarda Nesne Kullanımı

Nesne Parametre Olarak

static void bilgiYazdir(Ogrenci ogr) {
    System.out.println(ogr.isim + " (" + ogr.yas + ")");
}

// Kullanım
Ogrenci ali = new Ogrenci();
ali.isim = "Ali";
ali.yas = 20;
bilgiYazdir(ali);

Nesne referans olarak geçirilir. Metot içinde nesneyi değiştirirsen orijinal nesne değişir.

Nesne Döndüren Metot

static Ogrenci ogrenciOlustur(String isim, int yas) {
    Ogrenci o = new Ogrenci();
    o.isim = isim;
    o.yas = yas;
    return o;
}

// Kullanım
Ogrenci ali = ogrenciOlustur("Ali", 20);

Sınıf İçinde Sınıf Kullanma

Sınıflar birbirlerini field olarak kullanabilir. Bu, karmaşık yapılar modellemeye olanak sağlar.

class Adres {
    String sehir;
    String ilce;
    String sokak;
}

class Ogrenci {
    String isim;
    int yas;
    Adres adres;  // Adres nesnesi field olarak

    void adresiGoster() {
        if (adres != null) {
            System.out.println(isim + " - " + adres.sehir + "/" + adres.ilce);
        }
    }
}

// Kullanım
Adres ev = new Adres();
ev.sehir = "Istanbul";
ev.ilce = "Kadikoy";

Ogrenci ali = new Ogrenci();
ali.isim = "Ali";
ali.adres = ev;
ali.adresiGoster();  // Ali - Istanbul/Kadikoy

Bu composition (bileşim) kavramının temelidir: "bir öğrencinin adresi vardır" (has-a ilişkisi).

Tam Bir Örnek: Kütüphane Sistemi

class Kitap {
    String baslik;
    String yazar;
    boolean oduncAlindi;

    void bilgiGoster() {
        System.out.println("\"" + baslik + "\" - " + yazar +
            (oduncAlindi ? " [ÖDÜNÇTE]" : " [MEVCUT]"));
    }

    void oduncAl() {
        if (!oduncAlindi) {
            oduncAlindi = true;
            System.out.println(baslik + " ödünç alındı.");
        } else {
            System.out.println(baslik + " zaten ödünçte!");
        }
    }

    void iadeEt() {
        if (oduncAlindi) {
            oduncAlindi = false;
            System.out.println(baslik + " iade edildi.");
        } else {
            System.out.println(baslik + " zaten mevcut!");
        }
    }
}

public class Kutuphane {
    public static void main(String[] args) {
        Kitap k1 = new Kitap();
        k1.baslik = "Suç ve Ceza";
        k1.yazar = "Dostoyevski";

        Kitap k2 = new Kitap();
        k2.baslik = "1984";
        k2.yazar = "George Orwell";

        k1.bilgiGoster();
        k2.bilgiGoster();

        k1.oduncAl();
        k1.bilgiGoster();
        k1.oduncAl();    // zaten ödünçte!
        k1.iadeEt();
        k1.bilgiGoster();
    }
}

Bu örnek sınıf, nesne, field ve metot kavramlarının hepsini bir arada gösteriyor. Her Kitap nesnesi kendi durumunu (oduncAlindi) yönetiyor.

Yaygın Hatalar

Hata 1: new unutmak

Ogrenci o;
o.isim = "Ali";  // NullPointerException! new ile nesne oluşturulmadı

Hata 2: Nesne dizisinde new unutmak

Ogrenci[] liste = new Ogrenci[3];
liste[0].isim = "Ali";  // NullPointerException! liste[0] null
// Doğru: liste[0] = new Ogrenci(); yazıp sonra atama yap

Hata 3: == ile nesne karşılaştırma

Ogrenci a = new Ogrenci();
a.isim = "Ali";
Ogrenci b = new Ogrenci();
b.isim = "Ali";
System.out.println(a == b);  // false — farklı nesneler!

Özet

  • Sınıf (class) field ve metotlardan oluşan şablondur; nesne o şablondan new ile oluşturulan somut örnektir

  • Field'lar nesnenin verilerini, metotlar davranışlarını tutar

  • this anahtar kelimesi o anki nesneyi referans eder; parametre-field çakışmasını çözer

  • Nesneler referans ile tutulur: = ile atamak kopya oluşturmaz, aynı nesneye ikinci isim verir

  • null "hiçbir nesneye işaret etmiyor" demektir; null üzerinde işlem → NullPointerException

  • Sınıflar birbirlerini field olarak kullanabilir (composition — has-a ilişkisi)