İçeriğe geç

Object Sınıfı — Her Nesnenin Ortak Mirası

Başlangıç 8 dk Çok sık karşılaşılır

Önce şunu oku: Polimorfizm ve Dinamik Bağlama — Kararı Kim Veriyor?

30 saniyede özet

Java'daki her sınıf Object'ten türer ve ondan toString, equals ve hashCode'u miras alır. toString nesneyi tanıtır, equals iki nesnenin eşitliğine karar verir; equals'ı yazdıysan hashCode'u da yazarsın.

Bir ailenin bütün torunları büyük dededen bir şeyler taşır: bir soyadı, belki bir alışkanlık. Kimse bunu seçmez; doğuştan gelir.

Java’da bütün sınıfların ortak bir büyük dedesi vardır ve ondan birkaç alışkanlık miras alırlar.

Her sınıf Object'in torunudur ve üç metodu ondan miras alır; isterse kendi sürümünü yazar.
Adım adım oku
  1. En tepede Object sınıfı duruyor.
  2. String, ArrayList ve Hesap onun torunları.
  3. Üçü de toString, equals ve hashCode metotlarını miras alıyor.
  4. Hesap toString'in kendi sürümünü yazıyor; ötekiler mirası kullanmaya devam ediyor.
  1. Bayt: Hesabı log'a yazdırdım, ekranda Hesap@1b6d3586 çıktı. Bu ne?

  2. Sen: Hiç toString yazmış mıydın?

  3. Bayt: Hayır... Demek ki miras kalan toString'i kullanmış.

  4. Bayt: Büyük dededen gelen bu üç metodu tanıyalım. Birkaçını kendimiz yazacağız.

Her sınıfın gizli atası

Bir sınıfın başına extends yazmazsan Java onu kendiliğinden ObjectJava'daki bütün sınıfların en üstteki atası. extends yazılmayan her sınıf kendiliğinden ondan türer.Her nesneye toString, equals ve hashCode gibi metotları miras bırakır. Miras hâlleri basittir: equals yalnızca aynı nesne olup olmadığına bakar.Sözlükte gör → sınıfından türetir. Bu yüzden her nesnede birkaç hazır metot vardır.

MetotNe yaparMiras hâli
toString()Nesneyi metin olarak tanıtırSınıf adı, @ ve bir sayı
equals(Object)İki nesne eşit miYalnızca aynı nesne mi (==)
hashCode()Nesnenin rafını seçen sayıNesneye özgü bir sayı

Miras hâlleri güvenli ama çoğu zaman işe yaramaz. İki farklı hesap nesnesi aynı IBAN’ı taşısa bile miras equals onlara “farklı” der.

Kafam karıştı, daha basit anlat

Her sınıf, yazmasan bile Object’in çocuğudur. Object ona üç hazır metot bırakır; hazır hâlleri çok basittir, bu yüzden çoğu zaman kendi sürümünü yazarsın.

Hızlı kontrolBaşlangıç

`class Hesap { }` yazdın, hiç extends yok. Hesap hangi sınıftan türer?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

toString: nesnenin kendini tanıtması

Hesap sınıfında toString yazılmamış. `System.out.println(new Hesap("TR01"));` ne yazdırır? Cevabı göster

Hesap@1b6d3586 gibi bir şey: sınıfın adı, @ ve nesneye özgü bir sayının onaltılık hâli. İçindeki IBAN görünmez, çünkü miras toString alanları bilmez.

println, + ile metin birleştirme ve log kütüphaneleri nesneyi yazarken toString’i çağırır. Kendi toString’ini yazarsan nesne anlamlı bir metinle kendini tanıtır.

Nesne kendini tanıtıyor
@Override
public String toString() {
return "Hesap[iban=" + iban + ", bakiye=" + bakiye + "]";
}
// System.out.println(hesap) → Hesap[iban=TR01, bakiye=100]
Kafam karıştı, daha basit anlat

toString, nesnenin “ben kimim” cevabıdır. Yazmazsan Java kalıp bir cevap verir; yazarsan log’larda neye baktığını hemen anlarsın.

Hızlı kontrolBaşlangıç

toString yazılmamış bir Hesap nesnesini yazdırınca ekrana `Hesap@1b6d3586` gibi bir şey çıkıyor. Bu nereden geliyor?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Program ne yazdırır?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.
Esit.java
1class Hesap {
2 final String iban;
3 Hesap(String iban) { this.iban = iban; }
4}
5
6Hesap a = new Hesap("TR01");
7Hesap b = new Hesap("TR01");
8System.out.println(a.equals(b));
Java 21UTF-8LF

Satır satır: equals nasıl yazılır?

İki hesap aynı IBAN’ı taşıyorsa eşit sayılsın istiyoruz. Güvenli bir equals dört adımdan oluşur.

Güvenli bir equals

Hesap.java
1@Override
şu an çalışan satırpublic boolean equals(Object o) {
3 if (this == o) return true;
4 if (o == null || getClass() != o.getClass()) return false;
5 Hesap diger = (Hesap) o;
6 return iban.equals(diger.iban);
7}

Debug

Adım 1/4

imza Parametre Object olmalı. equals(Hesap) yazarsan miras metodun yerine geçmez, yanına yeni bir metot eklersin.

Java 21UTF-8LF2:1

Sol/sağ ok tuşlarıyla da gezebilirsin.

Hızlı kontrolBaşlangıç

Bu equals yazıldı ama `list.contains(new Hesap("TR01"))` hâlâ false dönüyor. Hatalı satır hangisi?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Hatalı satıra dokun, sonra kontrol et.

Hesap.java
Java 21UTF-8LF

equals’ın sözleri ve hashCode

equals’ın bir equals sözleşmesiequals metodunun uyması gereken kurallar: kendine eşit, simetrik, geçişli, tutarlı ve null'a eşit değil.Kardeş kural: equals true diyorsa hashCode'lar da eşit olmalı. Kurallar bozulursa HashMap, HashSet ve contains gibi yapılar şaşırır.Sözlükte gör → vardır. Nesne kendine eşittir; a b’ye eşitse b de a’ya eşittir; a b’ye, b c’ye eşitse a da c’ye eşittir; sonuç değişmedikçe aynı kalır; hiçbir nesne null’a eşit değildir.

Bir de kardeş kuralı var: equals’ı yazdıysan hashCode’u da aynı alanlarla yazarsın. Yoksa eşit iki nesne HashMap’te farklı raflara düşer ve biri bulunamaz; bunun ayrıntısı HashMap dersinde.

İkisi birlikte
@Override
public int hashCode() {
return iban.hashCode();
}

Bir sınıf yalnızca veri taşıyorsa record yaz: toString, equals ve hashCode’u bütün alanlarla senin yerine üretir.

Kafam karıştı, daha basit anlat

equals’ı yazdıysan hashCode’u da yaz, ikisi aynı alanlara baksın. Bunu elle yazmak istemiyorsan record kullan; Java üçünü de senin yerine yazar.

Aynı IBAN, aynı hesap mı?

Tohum 726867

Hesap a = new Hesap("TR01"); Hesap b = new Hesap("TR01");

    Oynat ya da adımla: her adımda bir kontrol çalışır.

    Hız
    Adım 0

    Şu an ne oldu?

    Yalnızca equals(Object)

    a ve b ayrı nesneler, ikisinin IBAN’ı da TR01.

    Görevler0/3

    • Listede bulunan nesneyi HashSet’te kaybetaçık

      İpucu

      Varsayılan ayarlar yeter.

    • a.equals(b) true olsun ama liste b’yi bulamasınaçık

      İpucu

      İmzaya dikkat.

    • Dört kontrolün hepsi beklenen cevabı versinaçık

      İpucu

      Sözleşmenin iki yarısı ve kendini tanıtma.

    Olay günlüğü (0)

    Henüz olay yok. Oynat veya adımla.

    1. Varsayılanla oynat. Yalnızca equals yazılı: liste b’yi buldu, HashSet bulamadı.
    2. “equals(Hesap)” seç. a.equals(b) true döndü, ama liste b’yi bulamadı: yanlış imza Object’in equals’ının yerine geçmedi.
    3. “equals(Object) + hashCode” seç ve “toString de yazıldı”yı aç. Dört kontrol de beklenen cevabı verdi.
    Hızlı kontrolBaşlangıç

    equals'ı IBAN'a göre yazdın ama hashCode'u yazmadın. Hangi sorun çıkar?

    Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

    Bir bankada bunun en tipik yeri IBAN gibi değer nesneleridir: boşluklu ya da boşluksuz yazılmış aynı IBAN eşit sayılmalı, log’da da okunur görünmelidir.

    Derinleş · Iban: eşitlik, hash ve okunur bir tanıtım 2 dosya · ~36 satır · ilk okumada atlayabilirsin
    Proje dosyaları

    src/main/java/com/bank/account/ Iban.java Kurucu IBAN'ı tek biçime getirir; equals ve hashCode aynı alana bakar.

    src/main/java/com/bank/account/Iban.java
    public final class Iban {
    private final String value;
    public Iban(String raw) {
    // "TR00 0001 ..." and "tr000001..." are the same IBAN.
    this.value = raw.replace(" ", "").toUpperCase(Locale.ROOT);
    }
    @Override
    public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    return value.equals(((Iban) o).value);
    }
    @Override
    public int hashCode() {
    return value.hashCode();
    }
    @Override
    public String toString() {
    return "Iban[****" + value.substring(value.length() - 4) + "]";
    }
    }

    src/main/java/com/bank/ Main.java toString okunur ama müşteriyi ele vermeyecek kadar kısaltılmış.

    src/main/java/com/bank/Main.java
    public class Main {
    public static void main(String[] args) {
    Iban a = new Iban("TR00 0001 0000 0000 0000 0000 01");
    Iban b = new Iban("tr000001000000000000000001");
    System.out.println(a.equals(b)); // true
    System.out.println(Set.of(a).contains(b)); // true: same hashCode too
    System.out.println(a); // Iban[****0001]
    }
    }

    Tuzaklar

    toString’e hassas veri koymak. toString log’lara, hata mesajlarına ve ekranlara gider; parola, T.C. kimlik numarası ya da tam kart numarası orada olmamalı, gerekiyorsa maskelenmeli.

    Değişen alanlarla equals ve hashCode. Nesne bir HashSet’e girdikten sonra o alan değişirse nesne yanlış rafta kalır. Eşitliği değişmeyen alanlara bağla.

    instanceof ile alt sınıf karışıklığı. Alt sınıf yeni bir alan ekleyip eşitliğe katarsa, a.equals(b) true iken b.equals(a) false çıkabilir. Emin değilsen getClass() karşılaştırması ya da final sınıf daha güvenlidir.

    Hızlı kontrolOrta

    Musteri sınıfının toString'i `"Musteri[ad=" + ad + ", tckn=" + tckn + ", sifre=" + sifre + "]"` döndürüyor. En büyük sorun nedir?

    Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

    Kendini sına

    Şimşek turu1/4

    extends yazılmayan bir sınıfın hiç üst sınıfı yoktur.

    Soru 1/3Orta

    Hangisi equals sözleşmesinin bir parçası değildir?

    Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

    Aklında kalacak üç şey

    1. 1 Her sınıf, extends yazmasa bile Object'ten türer ve toString, equals, hashCode metotlarını ondan miras alır.
    2. 2 equals'ın beş sözü vardır: kendine eşit, simetrik, geçişli, tutarlı ve null'a hiç eşit değil; bu sözler bozulursa koleksiyonlar şaşırır.
    3. 3 equals'ı yazdıysan hashCode'u da aynı alanlarla yazarsın; toString'e ise hassas veri koymazsın.
    Sonraki kapı Bir sınıf neden yalnızca tek bir sınıftan türeyebilir ama istediği kadar rol üstlenebilir? Interface ve Abstract Class — Rol mü, İskelet mi? · 8 dk

    5 kart sonraki derste seni bekliyor

    0/3 kart bu dersten toplandı

    Bu dersin üstüne kurulanlar

    Bunlar bu dersi temel alıyor; hazır olduğunda devam edebilirsin.