Bölüm 4: Nesne ve Sınıflar

Java ile Nesne Yönelimli Programlama
Sınıf ve nesneYapıcı metotlarNitelik ve metot türleristatic üyeler Erişim ve veri gizlemeReferanslar ve thisequals, toStringWrapper sınıflar record ve enumİç sınıflarSınıf tasarımı
Sercan KÜLCÜ · Giresun Üniversitesi · Elektrik-Elektronik Mühendisliği

Giriş

Öğrenme Çıktıları

Sınıf ve nesne

Sınıfı bir taslak, nesneyi o taslaktan üretilmiş somut bir örnek olarak açıklamak; nitelik ve metotlarıyla bir sınıf yazmak.

Nesne oluşturmak

new işlecini ve yapıcı metotları (constructor) kullanmak; varsayılan değerleri ve varsayılan yapıcıyı bilmek.

Örnek ve sınıf üyeleri

Örneğe ait ve static nitelik/metotları ayırt etmek; başlatıcı bloklarının çalışma sırasını izlemek.

Referanslar

Değişkenin nesneyi değil referansı tuttuğunu bellek çizimiyle göstermek; this, == ve equals farkını açıklamak.

Erişim ve gizleme

Erişim düzenleyicileri, erişimci (get) ve değiştirici (set) metotlarla veri gizlemeyi uygulamak.

Özel sınıf türleri

Wrapper sınıfları, record, enum ve iç sınıfları tanımak; iyi bir sınıf tasarımının üç unsurunu açıklamak.

Nesne Yönelimli Programlama

Nesne Yönelimli Programlama

  • Nesne yönelimli programlama (Object-Oriented Programming, OOP), programı birbiriyle etkileşen nesneler olarak kuran bir yaklaşımdır.
  • Nesne (object), gerçek dünyada açıkça tanımlanabilen bir varlığı temsil eder: bir öğrenci, bir masa, bir çember, ekrandaki bir düğme, hatta bir kredi.
  • Her nesnenin durumu (verileri) ve davranışı (yapabildikleri) vardır.
Benzetme: bir okul, öğrenci, öğretmen ve ders nesnelerinin birbirine mesaj göndermesiyle (metot çağırmasıyla) işler.
NesneNitelikler (durum)Davranışlar
Öğrenciad, numara, bölümderseKaydol(), notGor()
Masaen, boy, malzemetasi()
Çembermerkez, yarıçapalan(), cevre()
Düğmeyazı, renk, etkin mitikla()
Kreditutar, faiz, vadetaksitHesapla()

Nesne Yönelimli Programlama

Nesneler: Nitelik ve Davranış

  • Bir sınıfın üyeleri (members) vardır: nitelikler (fields), metotlar (methods) ve yapıcılar (constructors).
  • Nesneler veri saklar: bu veri parçalarına nitelik (alan, field) denir.
  • Nesneler işlem yapar: bu işlemlere davranış (metot, method) denir.
  • Veriyi ve o veri üzerinde çalışan kodu bir araya getirmek, programı daha düzenli, yeniden kullanılabilir ve sezgisel yapar.
ogrenci1 : Ogrenciad = "Ali"numara = 2012bolum = "EEM"selamVer()dersEkle(ad, not)ortalama()← nitelikler (fields)← davranışlar (methods)

Nesne Yönelimli Programlama

Prosedürel ve Nesne Yönelimli

Prosedürel (yordamsal) yaklaşımNesne yönelimli yaklaşım
Temel birimFonksiyon (metot)Nesne (veri + metotlar)
VeriAyrı değişkenlerde; her fonksiyon erişebilirNesnenin içinde; dışarıya kontrollü açılır
ÖrnekalanHesapla(en, boy)dikdortgen.alanHesapla()
Büyük programlarDeğişiklik birçok fonksiyonu etkilerDeğişiklik çoğunlukla bir sınıfın içinde kalır
Yeniden kullanımFonksiyonları kopyalayarakSınıfları kullanarak ve kalıtımla

Şimdiye kadar yazdığımız static metotlu programlar prosedürel tarzdaydı. Java'da her kod bir sınıfın içindedir; bu bölümde sınıfları nesne üretmek için kullanmaya başlıyoruz.

Nesne Yönelimli Programlama

Üç Temel Özellik

Sarmalama (Encapsulation)

Nesne, nitelik ve davranışlarının ayrıntısını diğer nesnelerden gizleyebilir. Dışarıya karşı kapalı bir kutu gibidir; yalnızca izin verilen metotlarla kullanılır.

Kalıtım (Inheritance)

Bir sınıf, başka bir sınıfın nitelik ve metotlarını miras alabilir. Kodun yeniden kullanımını ve sınıf hiyerarşisini sağlar.

Çok Biçimlilik (Polymorphism)

Bir nesne birden fazla biçim (tür) alabilir; aynı çağrı farklı nesnelerde farklı davranır. Esneklik ve dinamik davranış sağlar.

Bunlara çoğu zaman dördüncü olarak soyutlama (abstraction) eklenir: gereksiz ayrıntıyı gizleyip yalnızca önemli özellikleri göstermek. Bu bölüm temeli (sınıf ve nesne) kurar; sarmalama, kalıtım, çok biçimlilik ve soyut sınıflar sonraki bölümlerde ayrıntılı işlenir.

Sınıf ve Nesne

Sınıf: Nesnenin Taslağı

  • Sınıf (class), bir nesnenin taslağıdır (blueprint); bir sınıftan farklı verileri taşıyan birçok nesne üretilebilir.
  • Sınıf, nesnenin taşıyacağı verileri (nitelikler) ve yapabileceği işlemleri (metotlar) belirtir.
  • Bir nesne, bir sınıfın örneğidir (instance): sınıfın bellekteki somut hâlidir.
  • Sınıflar, gerçek dünyadaki varlıkları modellemeyi sağlar: bir Araba sınıfı her otomobili temsil edebilir; her marka ve model bu sınıftan üretilen bir nesnedir.
Sınıf (taslak)Arabamarkamodelyilrenkilerle()dur()sinyalVer()newaraba1 : ArabaToyota Corollaaraba2 : ArabaFord Mustangaraba3 : ArabaFiat EgeaNesneler (örnekler)

Benzetme: sınıf kurabiye kalıbı, nesneler o kalıpla kesilen kurabiyelerdir.

Sınıf ve Nesne

Örnek: Araba Sınıfı

Nitelikler (veriler)

Marka, Model, Yıl, Renk

Metotlar (işlemler)

Hareket et (ilerle), Dur, Sinyal ver

Aynı sınıftan üretilen iki nesne aynı nitelik adlarına ama farklı değerlere sahiptir.

Araba- marka : String- model : String- yil : int- renk : String+ ilerle() : void+ dur() : void+ sinyalVer() : voidaraba1 : Arabamarka = "Toyota"model = "Corolla"yil = 2022renk = "Gri"araba2 : Arabamarka = "Ford"model = "Mustang"yil = 2023renk = "Mavi"örneği

UML sınıf diyagramı: ad / nitelikler / metotlar; - private, + public. Nesne adları altı çizili yazılır.

Sınıf ve Nesne

Sınıf Tanımlama

public class Araba {
  // Nitelikler (fields)
  String marka;
  String model;
  int yil;
  String renk;

  // Metotlar (methods)
  void ilerle() {
    System.out.println(marka + " ilerliyor.");
  }

  void dur() {
    System.out.println(marka + " durdu.");
  }

  void sinyalVer() {
    System.out.println(marka + " sinyal veriyor.");
  }
}
  • class anahtar kelimesi ve sınıf adıyla başlar; gövde { } arasındadır.
  • Sınıf adı büyük harfle başlar (Araba, BankaHesabi); public bir sınıf, aynı adlı dosyada (Araba.java) bulunmalıdır.
  • Nitelikler sınıf gövdesinde, metotların dışında tanımlanır; her metot bu nitelikleri doğrudan kullanabilir.
  • Metotların önünde static yok: her biri belirli bir arabanın (nesnenin) metodudur.
  • Bu sınıfta main yok; tek başına çalışmaz, başka bir sınıf onu kullanır.

Sınıf ve Nesne

Sınıfın Kullanımı

public class AracTesti {
  public static void main(String[] args) {
    Araba araba1 = new Araba();
    araba1.marka = "Toyota";
    araba1.model = "Corolla";
    araba1.yil = 2022;
    araba1.renk = "Gri";

    Araba araba2 = new Araba();
    araba2.marka = "Ford";
    araba2.model = "Mustang";
    araba2.yil = 2023;
    araba2.renk = "Mavi";

    araba1.ilerle();
    araba2.sinyalVer();
    araba1.dur();
  }
}
Çıktı
Toyota ilerliyor.
Ford sinyal veriyor.
Toyota durdu.
  • new Araba() bir nesne üretir; araba1 onu gösterir.
  • araba1.marka = "Toyota";: nokta (.) ile nesnenin niteliğine erişilir.
  • araba1.ilerle(): metot, araba1'in verileriyle çalışır; araba2.sinyalVer() ise araba2'ninkilerle.
  • Nitelikleri dışarıdan böyle doğrudan değiştirmek iyi bir alışkanlık değildir; doğrusu yapıcı ve erişim metotları kullanmaktır.

Sınıf ve Nesne

Sınıfın Üyeleri

Nitelikler (fields)

Nesnelerin taşıyabileceği verileri temsil eder. Örnek: bir Ogrenci sınıfında ad ve soyad.

Metotlar (methods)

Nesnelerin gerçekleştirebileceği işlemleri tanımlar. Örnek: bir Kopek sınıfında havla() ve kos().

Erişim düzeyi

Her üye private, protected, varsayılan (yazılmaz) veya public olabilir: kimin kullanabileceğini belirler.

Sahiplik

Her üye nesneye ait (instance, varsayılan) veya static ile sınıfa ait olabilir.

Yapıcı metotlar da sınıfın içinde yazılır; ama yalnızca nesne oluşturulurken çalışırlar ve teknik olarak metot değil, ayrı bir üye türüdür. Sınıfın içinde başka sınıflar (iç sınıflar) da tanımlanabilir.

Sınıf ve Nesne

Erişim Düzenleyiciler

Erişim düzenleyiciler (access modifiers), bir sınıfa ve üyelerine sınıfın dışından nasıl erişilebileceğini belirtir.

DüzenleyiciAnlamıAynı sınıfAynı paketAlt sınıf (başka paket)Her yer
publicherkese açık✓✓✓✓
protectedkorumalı✓✓✓✗
(yazılmaz) varsayılanpaket düzeyi (package-private)✓✓✗✗
privateözel✓✗✗✗
  • Paket (package), birbiriyle ilgili sınıfların bulunduğu klasördür (package objects;).
  • Varsayılan erişim için bir anahtar kelime yoktur: default yazılmaz, hiçbir şey yazılmaz.
  • Genel kural: nitelikler private, dışarıya sunulan metotlar public.

Yapıcı Metotlar

Yapıcı Metotlar

  • Yapıcı metot (constructor), nesne oluşturmak için kullanılan özel bir metottur; new ile nesne oluşturulduğunda otomatik çağrılır.
  • Görevi, niteliklere ilk değerlerini vermek ve varsa başka hazırlık işlerini yapmaktır.
  • Adı sınıf adıyla aynıdır (büyük-küçük harf dahil).
  • Dönüş türü yoktur, void bile yazılmaz; değer döndüremez.
  • Genellikle public tanımlanır; nesne oluşturmayı kısıtlamak için private da olabilir (bkz. singleton).
  • Bir sınıfın birden çok yapıcısı olabilir (farklı parametrelerle).
public class Ogrenci {
  private String ad;
  private int numara;

  // Yapıcı: sınıfla aynı ad, dönüş türü yok
  public Ogrenci(String ad, int numara) {
    this.ad = ad;
    this.numara = numara;
  }
}

// Kullanımı:
Ogrenci ogr = new Ogrenci("Ali", 2012);

Yapıcı Metotlar

Nesne Nasıl Oluşturulur?

SinifAdi nesneAdi = new SinifAdi(parametreler);

Araba corolla = new Araba("Toyota", "Corolla", 2022);
Scanner klavye = new Scanner(System.in);
Kitap kitap = new Kitap();
import java.util.Scanner;
public class Olusturma {
  public static void main(String[] args) {
    Scanner klavye = new Scanner(System.in);
    StringBuilder metin = new StringBuilder("Java");
    String baslik = "Nesneler";           // kısayol
    String yazar = new String("Sercan");  // uzun yol
    metin.append(" 21");
    System.out.println(metin + " / " + baslik);
    System.out.println(yazar.length());
    System.out.println(klavye.nextInt() * 2);
  }
}

Kısayol: String baslik = "Nesneler"; String nesnesi oluşturur; yalnızca String baslik; ise sadece referans tanımlar.

  1. new, öbekte (heap) nesne için yer ayırır; nitelikler varsayılan değerleri alır.
  2. Yapıcı metot çağrılır, ilk değerleri verir.
  3. new ifadesinin sonucu nesnenin referansıdır; değişkene atanır.
Çıktı
(girdi: 21)
Java 21 / Nesneler
6
42

Yapıcı Metotlar

Yapıcı Örneği: Araba

public class Araba {
  private String model;
  private String renk;

  public Araba(String model, String renk) {
    this.model = model;
    this.renk = renk;
  }

  public void bilgiYazdir() {
    System.out.println(model + " - " + renk);
  }

}
public static void main(String[] args) {
  Araba sporAraba = new Araba("2022", "KIRMIZI");
  Araba klasikAraba = new Araba("2023", "BEYAZ");
  sporAraba.bilgiYazdir();
  klasikAraba.bilgiYazdir();
}
Yığın (stack)Öbek (heap)main()sporArabaklasikArabaAraba nesnesimodel"2022"renk"KIRMIZI"Araba nesnesimodel"2023"renk"BEYAZ"
Çıktı
2022 - KIRMIZI
2023 - BEYAZ

Yapıcı Metotlar

Referanslar

  • Bir nesne doğrudan kullanılamaz; ona yalnızca referans (reference, başvuru) ile erişilir. Değişkenlerde nesnenin kendisi değil, referansı saklanır.
  • Referans, nesnenin bellekte nerede olduğunu gösteren bir adres gibi düşünülebilir.
  • int, double, boolean gibi temel türlü değişkenler değeri kendileri tutar; sınıf türünden değişkenler (Araba, String, Scanner) referans tutar.
  • Hiçbir nesneyi göstermeyen referansın değeri null'dır.
Benzetme: değişken bir televizyon kumandası, nesne televizyondur. Kumandayı kopyalamak ikinci bir televizyon yaratmaz.
Yığın (stack)Öbek (heap)main()sporArabaklasikArabayeniArabanullAraba nesnesimodel"2022"renk"KIRMIZI"Araba nesnesimodel"2023"renk"BEYAZ"

Yerel değişkenler yığında (stack), nesneler öbekte (heap) bulunur; ok = referans.

Yapıcı Metotlar · Kodu adım adım çalıştır

new Araba(...): Adım Adım

Yığın (stack)Öbek (heap)main()sporAraba?klasikAraba?Araba #1modelnullrenknull

new öbekte yeni bir nesne ayırır; String nitelikler önce varsayılan değer null alır.

Yığın (stack)Öbek (heap)Araba(...)thismodel"2022"renk"KIRMIZI"main()sporAraba?klasikAraba?Araba #1modelnullrenknull

Yapıcı çağrılır: parametreler argümanların kopyasını alır, this yeni nesneyi gösterir.

Yığın (stack)Öbek (heap)Araba(...)thismodel"2022"renk"KIRMIZI"main()sporAraba?klasikAraba?Araba #1model"2022"renknull

this.model = model: soldaki nesnenin niteliği, sağdaki parametredir.

Yığın (stack)Öbek (heap)Araba(...)thismodel"2022"renk"KIRMIZI"main()sporAraba?klasikAraba?Araba #1model"2022"renk"KIRMIZI"

this.renk = renk: nesne artık hazır.

Yığın (stack)Öbek (heap)main()sporArabaklasikAraba?Araba #1model"2022"renk"KIRMIZI"

Yapıcı biter, çerçevesi silinir. new ifadesinin değeri olan referans sporAraba'ya atanır.

Yığın (stack)Öbek (heap)main()sporArabaklasikArabaAraba #1model"2022"renk"KIRMIZI"Araba #2model"2023"renk"BEYAZ"

Aynı adımlar ikinci kez: ayrı bir nesne oluşur, kendi model ve renk kopyalarıyla.

Yığın (stack)Öbek (heap)bilgiYazdir()thismain()sporArabaklasikArabaAraba #1model"2022"renk"KIRMIZI"Araba #2model"2023"renk"BEYAZ"

sporAraba.bilgiYazdir(): metotta this = #1, bu yüzden #1'in alanları yazılır.

Yığın (stack)Öbek (heap)bilgiYazdir()thismain()sporArabaklasikArabaAraba #1model"2022"renk"KIRMIZI"Araba #2model"2023"renk"BEYAZ"

Aynı metot, bu kez this = #2. Kod tek, veriler nesne başına ayrıdır.

public class Araba {
  private String model;
  private String renk;

  public Araba(String model, String renk) {
    this.model = model;
    this.renk = renk;
  }

  public void bilgiYazdir() {
    System.out.println(model + " - " + renk);
  }

  public static void main(String[] args) {
    Araba sporAraba = new Araba("2022", "KIRMIZI");
    Araba klasikAraba = new Araba("2023", "BEYAZ");
    sporAraba.bilgiYazdir();
    klasikAraba.bilgiYazdir();
  }
}

Yapıcı Metotlar

Varsayılan Yapıcı Metot

  • Sınıfa hiç yapıcı yazılmamışsa derleyici varsayılan yapıcıyı (default constructor) ekler: parametresiz, gövdesi boş. Nesne oluşturulurken her zaman bir yapıcı çağrılır.
  • Değer verilmeyen nitelikler varsayılan değer alır (yerel değişkenler almaz):
Nitelik türüVarsayılan değer
byte short int long0
float double0.0
booleanfalse
char'\u0000' (kod 0)
Referans (String, diziler, nesneler)null
class Nokta3 {
  int x;
  double agirlik;
  boolean gorunur;
  char harf;
  String ad;
}
public class Varsayilan {
  public static void main(String[] args) {
    Nokta3 n = new Nokta3();   // varsayılan yapıcı
    System.out.println(n.x + " " + n.agirlik);
    System.out.println(n.gorunur + " " + n.ad);
    System.out.println((int) n.harf);
  }
}
Çıktı
0 0.0
false null
0

Yapıcı Metotlar

Parametresiz ve Parametreli Yapıcı

public class Arac {
  private String marka;
  private String model;
  private int yil;
  public Arac() {                 // parametresiz yapıcı
    marka = "Bilinmiyor";
    model = "Bilinmiyor";
    yil = 0;
  }
  public Arac(String marka, String model, int yil) {
    this.marka = marka;
    this.model = model;
    this.yil = yil;
  }
  public void bilgiYazdir() {
    System.out.println(marka + " " + model + " " + yil);
  }
  public static void main(String[] args) {
    Arac a1 = new Arac();
    Arac a2 = new Arac("Renault", "Clio", 2021);
    a1.bilgiYazdir();
    a2.bilgiYazdir();
  }
}
Çıktı
Bilinmiyor Bilinmiyor 0
Renault Clio 2021
  • Arac(), kendi yazdığımız parametresiz yapıcıdır; nitelikleri anlamlı başlangıç değerlerine ayarlar.
  • İki yapıcı aynı adı taşır, parametreleri farklıdır: yapıcı aşırı yükleme. Hangisinin çalışacağını argümanlar belirler.
  • Sınıfa herhangi bir yapıcı yazıldığında derleyici artık varsayılan yapıcı eklemez. Yalnızca parametreli yapıcı varsa new Arac() derlenmez.

Nitelikler

Nitelikler ve Türleri

Nitelikler, sınıfın içinde (metotların dışında) tanımlanan veri değişkenleridir. İki temel türü vardır:

Örneğe ait alan (instance field)Sınıfa ait alan (static field)
Tanımprivate String ad;private static int toplamHesapSayisi;
Kopya sayısıHer nesnede ayrı bir kopyaSınıfta tek kopya, tüm nesneler paylaşır
Ne zaman oluşur?Her new ileSınıf belleğe yüklenirken, bir kez
Erişimnesne.adSinifAdi.toplamHesapSayisi
ÖrnekOgrenci: ad, soyadBankaHesabi: toplamHesapSayisi
  • Sabit (final) alanlara değer bir kez verilir, sonra değiştirilemez. Sınıf sabitleri genellikle static final ve BÜYÜK_HARF yazılır: Math.PI.
  • Sınıfa ait başlatıcılar (static { }) sınıf yüklenirken bir kez; örneğe ait başlatıcılar ({ }) her nesne oluşturulduğunda çalışır.

Nitelikler · Kodu adım adım çalıştır

static Sayaç: Adım Adım

Yığın (stack)Öbek (heap)Sınıf alanı (static): BankaHesabitoplamHesapSayisi0

Sınıf belleğe yüklenirken static alan bir kez oluşur ve 0 olur. Henüz hiç nesne yok.

Yığın (stack)Öbek (heap)Sınıf alanı (static): BankaHesabitoplamHesapSayisi1yapıcı metotthismain()h1?h2?h3?BankaHesabi #1hesapSahibi"Ali"

İlk nesne: kendi hesapSahibi kopyası "Ali" olur; ortak sayaç 1'e çıkar.

Yığın (stack)Öbek (heap)Sınıf alanı (static): BankaHesabitoplamHesapSayisi1main()h1h2?h3?BankaHesabi #1hesapSahibi"Ali"

h1 birinci nesneyi gösterir.

Yığın (stack)Öbek (heap)Sınıf alanı (static): BankaHesabitoplamHesapSayisi2main()h1h2h3?BankaHesabi #1hesapSahibi"Ali"BankaHesabi #2hesapSahibi"Ayşe"

İkinci nesnenin ayrı bir hesapSahibi alanı var; sayaç ise aynı alan: 2.

Yığın (stack)Öbek (heap)Sınıf alanı (static): BankaHesabitoplamHesapSayisi3main()h1h2h3BankaHesabi #1hesapSahibi"Ali"BankaHesabi #2hesapSahibi"Ayşe"BankaHesabi #3hesapSahibi"Can"

Üç nesne, üç hesapSahibi; ama tek toplamHesapSayisi = 3.

Yığın (stack)Öbek (heap)Sınıf alanı (static): BankaHesabitoplamHesapSayisi3main()h1h2h3BankaHesabi #1hesapSahibi"Ali"BankaHesabi #2hesapSahibi"Ayşe"BankaHesabi #3hesapSahibi"Can"

h2.hesapSahibi: örnek alanı nesne üzerinden okunur.

Yığın (stack)Öbek (heap)Sınıf alanı (static): BankaHesabitoplamHesapSayisi3static metotmain()h1h2h3BankaHesabi #1hesapSahibi"Ali"BankaHesabi #2hesapSahibi"Ayşe"BankaHesabi #3hesapSahibi"Can"

static metot sınıf adıyla çağrılır; this'i yoktur, yalnızca static alanı okur.

Yığın (stack)Öbek (heap)Sınıf alanı (static): BankaHesabitoplamHesapSayisi3main()h1h2h3sayi3BankaHesabi #1hesapSahibi"Ali"BankaHesabi #2hesapSahibi"Ayşe"BankaHesabi #3hesapSahibi"Can"

Dönen 3, sayi'ya atanır ve yazdırılır.

public class BankaHesabi {
  private String hesapSahibi;
  private static int toplamHesapSayisi = 0;

  public BankaHesabi(String hesapSahibi) {
    this.hesapSahibi = hesapSahibi;
    toplamHesapSayisi++;
  }

  public static int getToplamHesapSayisi() {
    return toplamHesapSayisi;
  }

  public static void main(String[] args) {
    BankaHesabi h1 = new BankaHesabi("Ali");
    BankaHesabi h2 = new BankaHesabi("Ayşe");
    BankaHesabi h3 = new BankaHesabi("Can");
    System.out.println(h2.hesapSahibi);
    int sayi = BankaHesabi.getToplamHesapSayisi();
    System.out.println(sayi);
  }
}

Nitelikler

Nitelik Tanımlamaları

public class Kitap {
  // Örneğe ait nitelikler
  private String baslik;
  private String yazar;
  private int sayfaSayisi;
  // Sınıfa ait alan
  private static int toplamKitapSayisi;
  // final tanımlanmış bir alan (sabit)
  public static final double PI = 3.14159265359;
}
public class Alanlar {
  public int a;                         // genel
  int b = 1, c = 2;                     // varsayılan (paket)
  private double x;                     // özel
  private static int xx;                // statik, özel
  public static int y;                  // statik, genel
  public final int CONST1 = 5;          // değiştirilemez
  private static final int CONST2 = 6;  // statik sabit
}
  • Söz dizimi: [erişim] [static] [final] tür ad [= ilkDeğer];
  • Aynı satırda birden çok alan: int b = 1, c = 2;
  • PI burada örnek olarak tanımlandı; Java'da hazır bir sabit vardır: Math.PI.
  • final alana yeniden değer atamak derleme hatasıdır:
    error: cannot assign a value to final variable CONST1

Nitelikler

Başlatıcı Blokları

Sınıfa ait başlatıcı (static initializer)

static { ... } bloğu, sınıf belleğe ilk kez yüklenirken, yalnızca bir kez çalışır. Static alanlara karmaşık ilk değer vermek için kullanılır.

Örneğe ait başlatıcı (instance initializer)

{ ... } bloğu, her nesne oluşturulduğunda, yapıcının gövdesinden önce çalışır. Tüm yapıcılarda ortak olan işleri yapar.

Bir nesne oluşturulurken sıra: (1) sınıf ilk kez kullanılıyorsa static alanlar ve static bloklar → (2) new ile bellek ayrılır, alanlar varsayılan değer alır → (3) alan ilk değerleri ve örnek başlatıcı blokları (yazılış sırasıyla) → (4) yapıcının gövdesi.

Sonraki slayttaki Kopek sınıfında her ikisi de var; çıktının sırasını tahmin edip sonra adım adım izleyin. İpucu: havla()'nın döndürdüğü değer yazdırılmıyor; System.out.println(d2.havla()); yazılsaydı son satır "Gece haw haw haw!" olurdu.

Nitelikler · Kodu adım adım çalıştır

Kopek: Başlatıcı Sırası

Yığın (stack)Öbek (heap)Kopek sınıfı yüklendistatic blok"çalıştı"

main çalışmadan önce sınıf yüklenir: static blok bir kez çalışır. (var, Java 10+: türü sağdan çıkarır; String... = String[].)

Yığın (stack)Öbek (heap)main()d1?d2?Kopek #1adinull

new Kopek("Kara"): nesne için yer ayrılır, adi = null.

Yığın (stack)Öbek (heap)Kopek(adi)thisadi"Kara"main()d1?d2?Kopek #1adinull

Yapıcının gövdesinden önce örnek başlatıcı bloğu çalışır.

Yığın (stack)Öbek (heap)Kopek(adi)thisadi"Kara"main()d1?d2?Kopek #1adi"Kara"

Şimdi yapıcı gövdesi: this.adi = adi.

Yığın (stack)Öbek (heap)Kopek(adi)thisadi"Kara"main()d1?d2?Kopek #1adi"Kara"

Yapıcı adı yazdırır: Kara.

Yığın (stack)Öbek (heap)main()d1d2Kopek #1adi"Kara"Kopek #2adi"Gece"

İkinci nesne: başlatıcı + yapıcı yeniden; static blok tekrar çalışmaz.

Yığın (stack)Öbek (heap)havla()thismain()d1d2Kopek #1adi"Kara"Kopek #2adi"Gece"

havla() bir metin döndürür ama değer kullanılmıyor: hiçbir şey yazılmaz.

public class Kopek {
  String adi;                 // nitelik
  Kopek(String adi) {         // yapıcı metot
    this.adi = adi;
    System.out.println(adi);
  }
  String havla() {            // örneğe ait metot
    return adi + " haw haw haw!";
  }
  static {                    // sınıfa ait başlatıcı
    System.out.println("Köpekler!");
  }
  {                           // örneğe ait başlatıcı
    System.out.println("Köpek oluşturuluyor.");
  }
  public static void main(String... strings) {
    var d1 = new Kopek("Kara");
    var d2 = new Kopek("Gece");
    d2.havla();
  }
}

Metotlar

Metot Türleri

  • Metotlar, sınıf içinde tanımlanan, belirli bir işi yapan kod bloklarıdır; sınıfın davranışını tanımlar.
  • Örneğe ait metotlar (instance methods) bir nesneyle ilişkilidir: telefon.aramaYap(...). O nesnenin niteliklerini kullanır.
  • Sınıfa ait metotlar (static) sınıfın kendisiyle ilişkilidir, tüm nesnelerde ortaktır: CepTelefonu üzerinden.
  • Static metotlar belirli bir nesneye bağlı olmadığı için nesneye özgü verilere (model gibi) doğrudan erişemez.
public class CepTelefonu {
  private String model;
  private static String isletimSistemi = "Sürüm 1";

  // Örneğe ait metot
  public void aramaYap(String numara) {
    System.out.println(model + " arıyor: " + numara);
  }

  // Örneğe ait metot
  public void mesajGonder(String alici, String mesaj) {
    System.out.println(alici + " <- " + mesaj);
  }

  // Sınıfa ait metot (static)
  public static void sistemiGuncelle(String yeniSurum) {
    isletimSistemi = yeniSurum;
  }
}

Metotlar

Metot Tanımlama

public int topla(int sayi1, int sayi2) {dönüş türüerişim düzeyimetot adıparametreler return sayi1 + sayi2;}gövde
  • Metot, sınıf içinde belirli bir görevi yapan kod bloğudur; kodun tekrar kullanılmasını ve düzenini sağlar.
  • Genel biçim: [erişim] [dönüş türü] ad([parametreler]) ve { gövde }.
  • Ad + parametre türleri metodun imzasıdır (signature).
ÖğeBelirlediğiÖrnek
Erişim düzeyi (access modifier)Başka sınıfların metoda nasıl erişebileceğipublic, private, protected, varsayılan
Dönüş türü (return type)Geri döndürülen değerin türüint, String, void, bir sınıf
Metot adı (method name)Çağırırken kullanılan adhesapla, verileriGoster, kameraAc
Parametreler (parameters)Metoda aktarılan girdilerint sayi1, int sayi2, String ad

Metotlar

Metot Örneği: Eposta

public class Eposta {
  public boolean gonder(String alici, String konu,
             String icerik) {
    // Gerçek gönderim yerine bir benzetim
    if (alici == null || !alici.contains("@")) {
      return false;               // başarısız
    }
    System.out.println(alici + " <- " + konu);
    return true;                    // başarılı
  }

  public static void main(String[] args) {
    Eposta e = new Eposta();
    boolean s1 = e.gonder("ali@ornek.com", "Ödev", "Ek");
    boolean s2 = e.gonder("ali.ornek.com", "Ödev", "Ek");
    System.out.println(s1 + " " + s2);
  }
}
gonder metodu
  • Ad: gonder
  • Parametreler: üç String: alıcı, konu, içerik
  • Dönüş türü: boolean, gönderim başarılı mı?
Çıktı
ali@ornek.com <- Ödev
true false

boolean döndüren metodun her yolu bir return ile bitmelidir; gövdesi yalnızca yorum olan bir metot missing return statement hatası verir.

Metotlar

Örneğe Ait Nitelikler ve Metotlar

  • Sınıf içinde static anahtar kelimesi olmadan tanımlanırlar.
  • Her nesne, niteliklerin kendi kopyasına sahiptir; nesneler farklı verilere sahip olabilir.
  • Nitelikler nesnenin özelliklerini, metotlar o nesnenin davranışını temsil eder.
  • Kullanabilmek için önce nesne oluşturmak gerekir: new, sonra nesne.metot().
  • Metot kodu tüm nesneler için tektir; her çağrıda hangi nesnenin verisiyle çalışacağını this belirler.
Örneğe aitstatic
Kime ait?NesneyeSınıfa
Çağrınesne.metot()Sinif.metot()
Nesne gerekir mi?EvetHayır
this var mı?EvetHayır
Örnekstr.length()Math.sqrt(x)

Metotlar

Nokta Operatörü

public class Telefon {
  String numara;
  public Telefon(String numara) {
    this.numara = numara;
  }
  public void aramaYap(Telefon telefon) {
    System.out.println(numara + " arıyor: " + telefon.numara);
  }
  public void mesajGonder(Telefon telefon, String mesaj) {
    System.out.println(telefon.numara + " <- " + mesaj);
  }
  public void kameraAc() {
    System.out.println(numara + " kamera açtı.");
  }
  public static void main(String[] args) {
    Telefon telefon1 = new Telefon("5551234567");
    Telefon telefon2 = new Telefon("5051234567");
    telefon1.aramaYap(telefon2);
    telefon2.mesajGonder(telefon1, "Merhaba!");
    telefon1.kameraAc();
  }
}
Çıktı
5551234567 arıyor: 5051234567
5551234567 <- Merhaba!
5551234567 kamera açtı.
  • Nesne oluşturulduktan sonra nitelik ve metotlarına nokta operatörü ile erişilir: nesne.metot(...), nesne.nitelik.
  • telefon1.aramaYap(...): telefon1 arar; metotta numara telefon1'in, telefon.numara telefon2'nin numarasıdır.
  • Bir nesne başka bir nesneyi parametre olarak alabilir.

Metotlar

Dikdörtgen Sınıfı

public class Dikdortgen {
  private double uzunluk;     // dikdörtgenin uzunluğu
  private double genislik;    // dikdörtgenin genişliği

  // Yapıcı metot
  public Dikdortgen(double uzunluk, double genislik) {
    this.uzunluk = uzunluk;
    this.genislik = genislik;
  }

  public double alanHesapla() {      // alanı hesaplar
    return uzunluk * genislik;
  }

  public double cevreHesapla() {     // çevreyi hesaplar
    return 2 * (uzunluk + genislik);
  }
}
  • Nitelikler private: dışarıdan yalnızca metotlarla kullanılır.
  • Yapıcı, iki kenarı alır ve nesneye kaydeder.
  • alanHesapla() ve cevreHesapla() parametre almaz: ihtiyaç duydukları veriler nesnenin içinde.
  • Prosedürel karşılığı alanHesapla(5.0, 3.0) olurdu; nesneyle dikdortgen.alanHesapla().

Metotlar · Kodu adım adım çalıştır

Dikdörtgen: Adım Adım

Yığın (stack)Öbek (heap)main()dikdortgenkarealan?cevre?Dikdortgen #1uzunluk5.0genislik3.0Dikdortgen #2uzunluk5.0genislik5.0

İki nesne, her biri kendi uzunluk ve genislik değerleriyle.

Yığın (stack)Öbek (heap)alanHesapla()thismain()dikdortgenkarealan?cevre?Dikdortgen #1uzunluk5.0genislik3.0Dikdortgen #2uzunluk5.0genislik5.0

dikdortgen.alanHesapla(): this = #1, sonuç 5.0 × 3.0 = 15.0.

Yığın (stack)Öbek (heap)cevre...()thismain()dikdortgenkarealan15.0cevre?Dikdortgen #1uzunluk5.0genislik3.0Dikdortgen #2uzunluk5.0genislik5.0

alan = 15.0. cevreHesapla(): 2 × (5.0 + 3.0) = 16.0.

Yığın (stack)Öbek (heap)main()dikdortgenkarealan15.0cevre16.0Dikdortgen #1uzunluk5.0genislik3.0Dikdortgen #2uzunluk5.0genislik5.0

double değerler 15.0 biçiminde yazılır.

Yığın (stack)Öbek (heap)alanHesapla()thismain()dikdortgenkarealan25.0cevre20.0Dikdortgen #1uzunluk5.0genislik3.0Dikdortgen #2uzunluk5.0genislik5.0

Aynı metotlar, bu kez this = #2 (kare): 25.0 ve 20.0. Eski değerlerin üzerine yazılır.

Yığın (stack)Öbek (heap)main()dikdortgenkarealan25.0cevre20.0Dikdortgen #1uzunluk5.0genislik3.0Dikdortgen #2uzunluk5.0genislik5.0

İkinci satır yazdırılır. Uzun bir deyim iki satıra bölünebilir; ; gelene kadar sürer.

public class DikdortgenTesti {
  public static void main(String[] args) {
    Dikdortgen dikdortgen = new Dikdortgen(5.0, 3.0);
    Dikdortgen kare = new Dikdortgen(5.0, 5.0);
    double alan = dikdortgen.alanHesapla();
    double cevre = dikdortgen.cevreHesapla();
    System.out.println("Alanı: " + alan
        + " Çevresi: " + cevre);
    alan = kare.alanHesapla();
    cevre = kare.cevreHesapla();
    System.out.println("Alanı: " + alan
        + " Çevresi: " + cevre);
  }
}

Veri Gizleme

Erişimciler ve Değiştiriciler

public class BankaHesabi {
  private double hesapBakiyesi;
  private String hesapSahibi;
  // Erişimciler (get)
  public double getHesapBakiyesi() {
    return hesapBakiyesi;
  }
  public String getHesapSahibi() {
    return hesapSahibi;
  }
  // Değiştiriciler (set)
  public void setHesapSahibi(String sahip) {
    hesapSahibi = sahip;
  }
  public void setHesapBakiyesi(double yeniBakiye) {
    if (yeniBakiye >= 0) {      // geçersizi reddet
      hesapBakiyesi = yeniBakiye;
    }
  }
}
  • Nitelikler, sınıf dışından doğrudan okunup değiştirilemesin diye private tanımlanır.
  • Erişimciler (accessors, getter): sınıfın dışından niteliklerin değerini okumak için; adı get + nitelik adı (boolean için is...).
  • Değiştiriciler (mutators, setter): niteliklere değer atamak için; adı set + nitelik adı.
  • Değiştirici, değeri atamadan önce denetleyebilir: burada negatif bakiye reddedilir.

Veri Gizleme

get / set Kullanımı

BankaHesabi hesap = new BankaHesabi();
hesap.setHesapSahibi("Ayşe");
hesap.setHesapBakiyesi(1500.0);
System.out.println(hesap.getHesapSahibi());
System.out.println(hesap.getHesapBakiyesi());
hesap.setHesapBakiyesi(-200);   // reddedilir
System.out.println(hesap.getHesapBakiyesi());
Çıktı
Ayşe
1500.0
1500.0
  • -200 reddedildi: bakiye 1500.0 olarak kaldı. Nesne kendi verisini korur.
  • Alana doğrudan erişmeye çalışmak derlenmez:
BankaHesabi hesap = new BankaHesabi();
hesap.hesapBakiyesi = -500;
error: hesapBakiyesi has private access in BankaHesabi

Veri Gizleme

Veri Gizleme

  • Veri gizleme (data hiding), nesnenin verilerini korumaya ve onlara güvenli erişmeye yardımcı olur.
  • Sınıfların dış dünyayla etkileşimini düzenler ve nesnenin bütünlüğünü korur (örneğin negatif bakiye olmaz).
  • Bir nesnenin niteliklerine yalnızca kendi sınıfının metotları doğrudan erişip değişiklik yapabilir.
  • Dışarıdan erişmek veya değiştirmek için sınıfın public metotları kullanılır.
hesap : BankaHesabiprivatehesapBakiyesihesapSahibigetHesapBakiyesi()getHesapSahibi()setHesapSahibi(s)setHesapBakiyesi(x)Dışkod✗yalnızca sınıfın kendimetotları erişir

Veri gizleme, sarmalamanın (encapsulation) temelidir; bir sonraki bölümde ayrıntılı işlenir.

static Üyeler

Statik Değişkenler ve Metotlar

public class Matematik {
  // Statik toplama metodu
  public static int toplama(int sayi1, int sayi2) {
    return sayi1 + sayi2;
  }

  public static void main(String[] args) {
    int sonuc = Matematik.toplama(5, 3);
    System.out.println("Toplama Sonucu: " + sonuc);
    System.out.println(Math.max(4, 9));
    System.out.println(Math.sqrt(16.0));
  }
}
  • static anahtar kelimesiyle tanımlanır; sınıfa aittir.
  • Statik üyelere erişmek için nesne oluşturmaya gerek yoktur; sınıf adı ve nokta kullanılır: SinifAdi.alanAdi, SinifAdi.metotAdi(argumanlar).
  • Nesne üzerinden de erişilebilir (nesne.alanAdi), ama tercih edilmez: okuyan kişi üyenin nesneye ait olduğunu sanır.
  • Hazır örnekler: Math.max(), Math.sqrt(), Math.PI, Integer.parseInt() ve main.
Çıktı
Toplama Sonucu: 8
9
4.0

static Üyeler

static Kuralları

Nereden →Örnek alan/metot kullanımıstatic alan/metot kullanımı
Örneğe ait metottan✓ doğrudan (ad, this.ad)✓ doğrudan
static metottan (main dahil)✗ ancak bir nesne üzerinden (ogr.ad)✓ doğrudan
public class Selam {
  private String ad = "Ali";
  public void selamVer() {
    System.out.println("Merhaba " + ad);
  }
  public static void main(String[] args) {
    selamVer();
  }
}
error: non-static method selamVer() cannot be referenced from a static context
public class Selam2 {
  private String ad = "Ali";
  public static void yaz() {
    System.out.println(ad);
  }
}
error: non-static variable ad cannot be referenced from a static context

Çözüm: nesne üzerinden çağırın (new Selam().selamVer();) ya da metodu static yapın.

Referanslar ve this

Referans Atama

  • Java'da nesneler referanslar (adresler) aracılığıyla işlenir.
  • araba2 = araba1; nesneyi kopyalamaz, referansı kopyalar: iki değişken aynı nesneyi işaret eder (takma ad, alias).
  • Biri üzerinden yapılan değişiklik diğerinden de görünür.
Kütüphane etiketiRaftaki etiket kitabın kendisi değil, yerini gösterir.
Araba anahtarıAnahtar arabayı işaret eder; iki anahtar aynı arabayı açar.
public class Araba {
  private String marka;

  public Araba(String marka) {
    this.marka = marka;
  }

  public String getMarka() {
    return marka;
  }

  public void setMarka(String marka) {
    this.marka = marka;
  }

}

Referanslar ve this · Kodu adım adım çalıştır

Referans Atama: Adım Adım

Yığın (stack)Öbek (heap)main()araba1araba2?Araba #1marka"Toyota"

Bir nesne oluşturulur; araba1 onu gösterir.

Yığın (stack)Öbek (heap)main()araba1araba2Araba #1marka"Toyota"

araba2 = araba1: referans kopyalanır. Hâlâ tek nesne var.

Yığın (stack)Öbek (heap)main()araba1araba2Araba #1marka"Toyota"

İki değişken aynı nesneyi okur: ikisi de Toyota.

Yığın (stack)Öbek (heap)setMarka()thismarka"Ford"main()araba1araba2Araba #1marka"Ford"

araba2.setMarka("Ford") ortak nesneyi değiştirir.

Yığın (stack)Öbek (heap)main()araba1araba2Araba #1marka"Ford"

araba1 üzerinden okuyunca da Ford: değişiklik paylaşılır.

Yığın (stack)Öbek (heap)main()araba1nullaraba2Araba #1marka"Ford"

araba1 = null: yalnızca bu değişkenin bağı kopar; nesne silinmez, araba2 onu göstermeye devam eder.

Yığın (stack)Öbek (heap)main()araba1nullaraba2Araba #1marka"Ford"

Nesneyi gösteren son referans da kaybolursa nesne çöp toplayıcı (garbage collector) tarafından silinir.

public static void main(String[] args) {
  Araba araba1 = new Araba("Toyota");
  Araba araba2 = araba1;
  System.out.println("Araba 1: " + araba1.getMarka());
  System.out.println("Araba 2: " + araba2.getMarka());
  araba2.setMarka("Ford");
  System.out.println("Araba 1: " + araba1.getMarka());
  araba1 = null;
  System.out.println("Araba 2: " + araba2.getMarka());
}

Referanslar ve this

null ve NullPointerException

public class Bos {
  String ad;

  public static void main(String[] args) {
    Bos b = null;
    System.out.println(b.ad.length());
  }
}
Exception in thread "main" java.lang.NullPointerException: Cannot read field "ad" because "<local1>" is null
    at Bos.main(Bos.java:6)

Yerel değişken hiç değer verilmeden kullanılırsa program derlenmez: error: variable sb might not have been initialized

  • null, referans değişkeninin hiçbir nesneyi göstermediği anlamına gelir.
  • null bir referans üzerinden nitelik okumak ya da metot çağırmak çalışma zamanında NullPointerException fırlatır.
  • Önlem: kullanmadan önce kontrol edin: if (b != null) { ... }
  • Hiçbir referansın göstermediği nesneler JVM'in çöp toplayıcısı tarafından otomatik silinir; Java'da nesneyi elle silmek gerekmez.

Referanslar ve this

this Anahtar Kelimesi

public class Golge {
  private String ad;

  public Golge(String ad) {
    ad = ad;            // this unutuldu!
  }

  public static void main(String[] args) {
    Golge g = new Golge("Ali");
    System.out.println(g.ad);
  }
}
Çıktı
null
  • this, metodun çağrıldığı nesneyi işaret eden referanstır.
  • static metotlarda kullanılamaz (orada nesne yoktur).
  • En sık yapıcılarda, nitelik adı ile parametre adı aynı olduğunda kullanılır: this.ad = ad;
  • Soldaki kodda this unutulmuş: ad = ad; parametreyi kendine atar, nitelik null kalır. Derleyici hata vermez!
  • this(...) ise aynı sınıfın başka bir yapıcısını çağırır.

Referanslar ve this

this ile Nesneyi Aktarmak

public class Takim {
  private String ad;
  public Takim(String ad) {
    this.ad = ad;
  }
  public void oyuncuEkle(Oyuncu oyuncu) {
    oyuncu.takimaKatil(this);   // bu nesne
  }
  public String getAd() {
    return ad;
  }
  public static void main(String[] args) {
    Takim takim = new Takim("Giresunspor");
    Oyuncu oyuncu = new Oyuncu("Mert");
    takim.oyuncuEkle(oyuncu);
  }
}
  • this, o anki nesneyi başka bir metoda parametre olarak iletmek için kullanılır.
  • takim.oyuncuEkle(oyuncu) içinde this = takim nesnesi; takimaKatil(this) ile oyuncuya verilir.
  • Aynı dosyada ikinci sınıf (public değil):
class Oyuncu {
  private String ad;
  Oyuncu(String ad) {
    this.ad = ad;
  }
  void takimaKatil(Takim takim) {
    String t = takim.getAd();
    System.out.println(ad + " -> " + t);
  }
}
Çıktı
Mert -> Giresunspor

Referanslar ve this · Kodu adım adım çalıştır

this ile Selam: Adım Adım

Yığın (stack)Öbek (heap)Ogrenci(ad)thisad"Ali"main()ogrenci1?ogrenci2?Ogrenci #1ad"Ali"

Yapıcıda this yeni nesnedir: this.ad (nitelik) = ad (parametre).

Yığın (stack)Öbek (heap)main()ogrenci1ogrenci2Ogrenci #1ad"Ali"Ogrenci #2ad"Ayşe"

İkinci nesne de aynı yapıcıyla oluşur; o sırada this = #2 idi.

Yığın (stack)Öbek (heap)selamVer()thismain()ogrenci1ogrenci2Ogrenci #1ad"Ali"Ogrenci #2ad"Ayşe"

ogrenci1.selamVer(): noktanın solundaki nesne this olur → "Ali".

Yığın (stack)Öbek (heap)selamVer()thismain()ogrenci1ogrenci2Ogrenci #1ad"Ali"Ogrenci #2ad"Ayşe"

Aynı kod, farklı this → "Ayşe". Burada this.ad yerine ad yazmak da aynıdır.

public class Ogrenci {
  private String ad;

  public Ogrenci(String ad) {
    this.ad = ad;
  }

  public void selamVer() {
    System.out.println("Merhaba, ben " + this.ad);
  }

  public static void main(String[] args) {
    Ogrenci ogrenci1 = new Ogrenci("Ali");
    Ogrenci ogrenci2 = new Ogrenci("Ayşe");
    ogrenci1.selamVer();
    ogrenci2.selamVer();
  }
}

Metot Aşırı Yükleme

Metot Aşırı Yükleme

public class HesapMakinesi {
  // İki tamsayıyı topla
  public int topla(int sayi1, int sayi2) {
    return sayi1 + sayi2;
  }
  // İki ondalık sayıyı topla
  public double topla(double sayi1, double sayi2) {
    return sayi1 + sayi2;
  }
  // Üç tamsayıyı topla
  public int topla(int sayi1, int sayi2, int sayi3) {
    return sayi1 + sayi2 + sayi3;
  }

  public static void main(String[] args) {
    HesapMakinesi hm = new HesapMakinesi();
    System.out.println(hm.topla(5, 3));
    System.out.println(hm.topla(3.5, 2.5));
    System.out.println(hm.topla(4, 6, 8));
    System.out.println(hm.topla(2, 3.5));
  }
}
Çıktı
8
6.0
18
5.5
  • Aşırı yükleme (method overloading): farklı veri türü veya sayıda parametreyle aynı işi yapan, aynı adlı metotlar.
  • Hangisinin çalışacağına derleyici argümanlara bakarak karar verir. topla(2, 3.5): 2, double'a genişletilir.
  • Yalnızca dönüş türü farklıysa olmaz:
error: method topla(int,int) is already defined in class Hesap2

Nesneleri Karşılaştırma

== ve equals()

  • Değişkenler yalnızca nesnelere ait referansları saklar.
  • == işleci nesnelerin nitelikleri yerine bellek adreslerini karşılaştırır: iki değişken aynı nesneyi mi gösteriyor?
  • İki nesnenin içerik eşitliği için tüm özellikleri karşılaştıran equals() kullanılır; kendi sınıflarımızda yeniden yazılmalıdır.
  • String ve wrapper'lar da nesnedir: klavyeden okunan "Java" ile "Java" sabiti == ile false, equals ile true verdi.
Yığın (stack)Öbek (heap)main()k1k2k3Kisi #1ad"Ali"yas20Kisi #2ad"Ali"yas20
İfadeSonuç
k1 == k3true: aynı nesne
k1 == k2false: farklı nesneler
k1.equals(k2)true: aynı içerik*

* equals yeniden yazıldıysa; yoksa Object'in sürümü == gibi davranır.

Nesneleri Karşılaştırma

equals() Metodunu Yazmak

public class Kisi {
  private String ad;
  private int yas;
  public Kisi(String ad, int yas) {
    this.ad = ad;
    this.yas = yas;
  }
  @Override
  public boolean equals(Object obj) {
    // Aynı referansa sahipse, eşittir.
    if (this == obj)
      return true;
    // Null kontrolü yapılır, nesne türü karşılaştırılır.
    if (obj == null || getClass() != obj.getClass())
      return false;
    // Kisi nesnelerinin alanları karşılaştırılır.
    Kisi kisi = (Kisi) obj;
    return yas == kisi.yas && ad.equals(kisi.ad);
  }
  @Override
  public int hashCode() {
    return 31 * ad.hashCode() + yas;
  }
}

k1, k2 = new Kisi("Ali", 20), k3 = k1 için çıktı:

k1 == k2false
k1.equals(k2)true
k1 == k3true
k1.equals(null)false
k1.hashCode() == k2.hashCode()true
  • Parametre türü Object olmalıdır; @Override imzayı derleyiciye denetletir.
  • null kontrolü hatayı önler.
  • equals yazılınca hashCode da yazılmalıdır: eşit nesneler eşit hash vermeli.

Nesneleri Karşılaştırma

getClass() ve instanceof

class Hayvan { }
class Kopek extends Hayvan { }
public class TurKontrol {
  public static void main(String[] args) {
    Hayvan h = new Kopek();
    Hayvan h2 = new Hayvan();
    Hayvan yok = null;
    System.out.println(h.getClass().getSimpleName());
    System.out.println(h.getClass() == Hayvan.class);
    System.out.println(h instanceof Kopek);
    System.out.println(h instanceof Hayvan);
    System.out.println(h2 instanceof Kopek);
    System.out.println(yok instanceof Hayvan);
    if (h instanceof Kopek k) {      // Java 16+
      System.out.println("Köpek: " + k.getClass());
    }
  }
}
Çıktı
Kopek
false
true
true
false
false
Köpek: class Kopek
  • getClass(): Object'te tanımlıdır; nesnenin çalışma zamanındaki gerçek sınıfını döndürür.
  • instanceof: nesne o türden veya alt sınıfından ise true; null için false. Tür dönüşümünden (cast) önce kullanılır.
  • extends (kalıtım) ile her Kopek bir Hayvan'dır; ayrıntısı Kalıtım bölümünde.

Nesneleri Karşılaştırma

toString() Metodu

class Ogrenci {
  private String ad;
  private int numara;
  Ogrenci(String ad, int numara) {
    this.ad = ad;
    this.numara = numara;
  }
  @Override
  public String toString() {
    return "Ogrenci [ad=" + ad + ", numara=" + numara + "]";
  }
}
public class YaziTesti {
  public static void main(String[] args) {
    Ogrenci ogr = new Ogrenci("Ali", 2012);
    Ogrenci yok = null;
    System.out.println(ogr);              // toString()
    System.out.println("Kayıt: " + ogr);  // birleştirme
    System.out.println(yok);              // null
    System.out.println(new Ders());       // Object'inki
  }
}
Çıktı
Ogrenci [ad=Ali, numara=2012]
Kayıt: Ogrenci [ad=Ali, numara=2012]
null
Ders@87aac27
  • Nesnenin metin temsilini döndüren Object metodu; println ve + onu otomatik çağırır.
  • Yeniden yazılmazsa SinifAdi@hashKodu döner (çalıştırmaya göre değişir); Ders sınıfı toString yazmamıştır.

Wrapper Sınıflar

Wrapper Sınıflar

Temel türWrapper sınıf
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
charCharacter
booleanBoolean
  • Wrapper (sarmalayıcı) sınıflar, temel veri türlerini nesne olarak temsil eder.
  • Bazı yerlerde nesne gerekir: ArrayList<Integer> gibi generic koleksiyonlar temel tür alamaz.
  • Temel türe null atanamaz; wrapper değişkene atanabilir ("değer yok").
  • Yardımcı metotlar sağlar: Integer.parseInt("12"), Integer.MAX_VALUE, Character.isDigit(c).
  • Temel türler daha hızlı ve az bellek kullanır; gerekmedikçe temel türü tercih edin.
  • Autoboxing ve unboxing dönüşümlerine dikkat edilmelidir.

Wrapper Sınıflar

Autoboxing ve Unboxing

public class Sarmalayici {
  public static void main(String[] args) {
    // int tipinde bir değişken
    int sayi = 42;
    // Integer wrapper sınıfı kullanımı
    Integer wrapperSayi = Integer.valueOf(sayi);
    // Autoboxing (otomatik ambalajlama)
    Integer wrapperSayi2 = sayi;
    // Unboxing (açık ve otomatik)
    int sayi2 = wrapperSayi2.intValue();
    int sayi3 = wrapperSayi2;
    System.out.println(sayi2 + sayi3);
    System.out.println(wrapperSayi.equals(wrapperSayi2));
    System.out.println(Integer.parseInt("123") + 1);
    System.out.println(Integer.MAX_VALUE);
    System.out.println(Character.isDigit('7'));
    System.out.println(Double.parseDouble("2.5") * 2);
    Integer bos = null;      // int bos = null; derlenmez
    System.out.println(bos);
  }
}
  • Autoboxing: temel tür → wrapper, otomatik. Unboxing: wrapper → temel tür.
  • Açık biçimleri: Integer.valueOf(sayi), w.intValue().
Çıktı
84
true
124
2147483647
true
5.0
null

Wrapper Sınıflar

Wrapper Tuzakları

import java.util.ArrayList;
public class Tuzaklar {
  public static void main(String[] args) {
    ArrayList<Integer> liste = new ArrayList<>();
    liste.add(5);                 // autoboxing: 5 -> Integer
    int ilk = liste.get(0);       // unboxing: Integer -> int
    System.out.println(ilk + 1);
    Integer a = 127, b = 127;
    Integer c = 128, d = 128;
    System.out.println(a == b);
    System.out.println(c == d);
    System.out.println(c.equals(d));
    Integer bos = null;
    int x = bos;                  // NullPointerException
  }
}
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "java.lang.Integer.intValue()" because "<local7>" is null
Çıktı
6
true
false
true
  • Wrapper nesneleri == ile karşılaştırmayın: referans karşılaştırır. −128…127 arası değerler önbellekten aynı nesne olarak gelir; 128 için false.
  • Her zaman equals() kullanın.
  • null bir wrapper'ı açmak (unboxing) NullPointerException fırlatır.

Kayıt ve enum

Kayıtlar (Records)

  • Kayıt (record, Java 16+), yalnızca veri taşıyan sınıfları kısa ve temiz yazmak için tasarlanmış bir sınıf türüdür.
  • Değişmez (immutable) nesneleri temsil eder: tüm nitelikler private final'dır; set metodu yoktur.
  • Derleyici otomatik üretir: yapıcı, erişim metotları x() ve y() (adları get ile başlamaz), equals, hashCode, toString.
record Nokta(double x, double y) { }

Bu tek satır; iki alan, yapıcı, iki erişimci ve üç Object metodu içeren yaklaşık 30 satırlık bir sınıfa denktir.

public class KayitTesti {
  public static void main(String[] args) {
    Nokta nokta1 = new Nokta(1.0, 2.5);
    Nokta nokta2 = new Nokta(1.0, 2.5);
    boolean esitMi = nokta1.equals(nokta2);
    System.out.println(esitMi);
    System.out.println(nokta1 == nokta2);
    System.out.println(nokta1);
    System.out.println(nokta1.x() + nokta1.y());
  }
}
Çıktı
true
false
Nokta[x=1.0, y=2.5]
3.5
n.x = 3.0;   →   error: x has private access in Nokta

Kayıt ve enum

enum (Numaralandırma Türü)

enum HaftaGunleri {
  PAZARTESI, SALI, CARSAMBA, PERSEMBE,
  CUMA, CUMARTESI, PAZAR
}
public class GunTesti {
  public static void main(String[] args) {
    HaftaGunleri[] tumGunler = HaftaGunleri.values();
    HaftaGunleri persembe = HaftaGunleri.valueOf("PERSEMBE");
    System.out.println(tumGunler.length + " gün");
    System.out.println(persembe + " " + persembe.ordinal());
    for (HaftaGunleri gun : tumGunler) {
      boolean haftaSonu = gun == HaftaGunleri.CUMARTESI
          || gun == HaftaGunleri.PAZAR;
      if (haftaSonu) {
        System.out.println(gun + ": hafta sonu");
      }
    }
  }
}
Çıktı
7 gün
PERSEMBE 3
CUMARTESI: hafta sonu
PAZAR: hafta sonu
  • enum, sabit ve sınırlı değerleri temsil eden özel bir türdür.
  • values() tüm değerleri dizi olarak verir; üzerinde döngü kurulabilir.
  • valueOf metinden değere çevirir; ordinal() 0'dan başlayan sıra. Değerler == ile karşılaştırılır.

İç Sınıflar

İç Sınıflar (Inner Classes)

  • İç sınıf, bir sınıfın içinde tanımlanan sınıftır. Dış sınıfın niteliklerine ve metotlarına (private olanlar dahil) doğrudan erişebilir.
  • Yalnızca bir sınıfın işine yarayan yardımcı sınıfları gruplamak için kullanılır; grafik arayüzlerde olay dinleyici (listener) sınıfları için çok yaygındır.
TürNerede tanımlanır?Nasıl oluşturulur?
Statik iç sınıfSınıf gövdesinde, static ileDış sınıf nesnesi olmadan: new Outer.StaticInner()
Üye iç sınıfSınıf gövdesinde, static olmadanBir dış sınıf nesnesi üzerinden: outer.new MemberInner()
Yerel iç sınıfBir metodun içindeYalnızca o metodun içinden
Anonim iç sınıfBir ifadenin içinde, adsızTanımlandığı yerde tek nesne; bir arayüzü veya soyut sınıfı gerçekler

İç Sınıflar

Statik İç Sınıf

public class Outer {
  // Dış sınıfın içinde statik bir iç sınıf
  static class StaticInner {
    void display() {
      System.out.println("Statik İç Sınıf");
    }
  }

  public static void main(String[] args) {
    // Dış sınıf örneği oluşturmadan erişim
    Outer.StaticInner staticInner = new Outer.StaticInner();
    staticInner.display();
  }
}
Çıktı
Statik İç Sınıf
  • static anahtar kelimesiyle tanımlanır.
  • Dış sınıfın bir nesnesi olmadan oluşturulabilir: new Outer.StaticInner().
  • Dış sınıfın yalnızca static üyelerine doğrudan erişebilir.

İç Sınıflar

Üye İç Sınıf

public class Outer {
  private int sayi = 5;          // dış sınıfın özel alanı

  class MemberInner {            // üye iç sınıf
    void display() {
      System.out.println("Üye İç Sınıf, sayi = " + sayi);
    }
  }

  public static void main(String[] args) {
    // Dış sınıf örneği üzerinden üye iç sınıfa erişim
    Outer outer = new Outer();
    Outer.MemberInner memberInner = outer.new MemberInner();
    memberInner.display();
  }
}
Çıktı
Üye İç Sınıf, sayi = 5
  • Dış sınıfın bir üyesi olarak (static olmadan) tanımlanır.
  • Her üye iç sınıf nesnesi bir dış nesneye bağlıdır: outer.new MemberInner(). Bu yüzden private sayi'yi okuyabilir.
  • main içinde doğrudan new MemberInner() derlenmez:
error: non-static variable this cannot be referenced from a static context

İç Sınıflar

Yerel İç Sınıf

public class Outer {
  void outerMethod() {
    class LocalInner {         // metodun içinde tanımlanır
      void display() {
        System.out.println("Yerel İç Sınıf");
      }
    }
    // Yerel iç sınıfa yalnızca bu metodun içinden erişilir
    LocalInner localInner = new LocalInner();
    localInner.display();
  }

  public static void main(String[] args) {
    Outer outer = new Outer();
    outer.outerMethod();
  }
}
Çıktı
Yerel İç Sınıf
  • Bir metodun içinde tanımlanır; yalnızca o metodun içinden kullanılabilir.
  • Metot dışında LocalInner adı bilinmez.
  • Bir metodun içinde birkaç kez gereken küçük bir yardımcı tür için kullanılır.

İç Sınıflar

Anonim İç Sınıf

interface MyInterface {
  void myMethod();
}

public class Outer {
  public static void main(String[] args) {
    // Genellikle arayüzleri veya soyut sınıfları uygular
    MyInterface myInterface = new MyInterface() {
      @Override
      public void myMethod() {
        System.out.println("Anonim İç Sınıf");
      }
    };
    myInterface.myMethod();
  }
}
Çıktı
Anonim İç Sınıf
  • Adı olmayan sınıftır; tanımlandığı yerde tek bir nesnesi oluşturulur.
  • Genellikle bir arayüzü (interface) veya soyut sınıfı gerçekler: new ArayuzAdi() { ... }; Sondaki ; atama deyimine aittir.
  • Tek metotlu arayüzler için Java 8+ lambda daha kısadır: () -> ...

Sınıf Türleri ve Tasarım

Sınıflar ve Türler

interface Printable { ... }
interface Runner { ... }
class Hayvan implements Printable, Serializable { ... }
class Kopek extends Hayvan implements Runner { ... }
var kazanan = new Kopek(...);
  • Bir nesne tek bir sınıfa ait olabilir, ama birçok türe sahip olabilir.
  • kazanan yalnızca Kopek sınıfına aittir.
  • Ama türleri: Kopek, Runner, Hayvan, Printable, Serializable, Object; hepsi için instanceof true verir.
  • Bu, çok biçimliliğin temelidir.
Object«interface»Printable«interface»SerializableHayvan«interface»RunnerKopekextendsextends

Düz çizgi + boş üçgen: kalıtım (extends); kesikli: gerçekleme (implements).

Sınıf Türleri ve Tasarım

Sınıf Çeşitleri

Sınıf, bir nesnenin yapısını ve davranışını tanımlayan bir şablondur. Amaçlarına göre farklı sınıf çeşitleri vardır:

ÇeşitÖzellikÖrnek
Numaralandırma (enum)Sabit bir nesne kümesine sahiptirenum Gun { PAZARTESI, SALI, ... }
SingletonYalnızca bir nesnesi oluşturulabilirprivate yapıcı + static tek nesne
Soyut (abstract)Kendi nesnesi oluşturulamazabstract class Sekil
Mühürlü (sealed, Java 17+)Alt sınıfları sabit bir kümedirsealed interface Hareket permits Yuru, Kos
FinalAlt sınıf türetilemezfinal class String
Veri (record)Nesneleri değiştirilemez (immutable)record Nokta(double x, double y)
Araç (utility)Yalnızca static metotlar içerirMath, Arrays
Uygulama (application)main metodunu içerirProgramın başladığı sınıf

Sınıf Türleri ve Tasarım

Sınıf Çeşitleri: Örnek

final class Araclar {             // araç ve final sınıf
  private Araclar() { }         // nesne oluşturulamaz
  static int kare(int x) { return x * x; }
}
class Ayarlar {                   // singleton
  private static final Ayarlar TEK = new Ayarlar();
  private Ayarlar() { }
  static Ayarlar getir() { return TEK; }
}
abstract class Sekil {            // soyut sınıf
  abstract double alan();
}
// mühürlü (sealed, Java 17+)
sealed interface Hareket permits Yuru, Kos { }
final class Yuru implements Hareket { }
final class Kos implements Hareket { }
public class Cesitler {           // uygulama sınıfı
  public static void main(String[] args) {
    System.out.println(Araclar.kare(7));
    System.out.println(Ayarlar.getir() == Ayarlar.getir());
  }
}
Çıktı
49
true
  • Araclar: private yapıcı ile nesne oluşturulamaz, yalnızca static metot; final ile türetilemez.
  • Ayarlar: tek nesne her seferinde aynıdır, bu yüzden == true.
  • new Sekil() derleme hatası verir (soyut); Hareket'i yalnızca Yuru ve Kos gerçekleyebilir.

Sınıf Türleri ve Tasarım

Sınıf Tasarımı

Sınıfları tasarlarken üç temel unsura dikkat edilmelidir:

1. Tanımlama (Specification)Yapının nasıl kullanılacağını belirler: yapıcı ve metotlar imzalarıyla tanımlanır. Soyutlama, değişikliğin etki alanını azaltır.

Kullanıcı yalnızca bu "sözleşmeyi" bilir.

2. Temsil (Representation)Düşük seviyeli yapısal ayrıntılardır; genellikle nitelik tanımlarıyla temsil edilir. private tutulmalı, dış dünyaya sınıfın iç yapısı hakkında bilgi verilmemelidir.

Temsil değişse bile kullanıcı kodu bozulmaz.

3. Uygulama (Implementation)Yapıcı ve metotların içeriğidir: davranışı gerçekleştiren kod. Ayrıntıları gizli tutulmalı; kullanıcı yalnızca tanımlanan arayüzle etkileşmelidir.

Sonraki slaytta üç unsur tek bir sınıfta.

Sınıf Türleri ve Tasarım

Tasarım Örneği: RasyonelSayi

public class RasyonelSayi {
  // Temsil: gizli alanlar
  private int pay, payda;
  // Tanımlama: public yapıcı ve metotlar
  public RasyonelSayi(int pay, int payda) {
    int e = ebob(Math.abs(pay), Math.abs(payda));
    this.pay = pay / e;
    this.payda = payda / e;
  }
  public RasyonelSayi topla(RasyonelSayi d) {
    int yeniPay = pay * d.payda + d.pay * payda;
    return new RasyonelSayi(yeniPay, payda * d.payda);
  }
  @Override
  public String toString() { return pay + "/" + payda; }
  // Uygulama ayrıntısı: gizli yardımcı metot
  private static int ebob(int a, int b) {
    while (b != 0) { int k = a % b; a = b; b = k; }
    return a;
  }
}
  • Tanımlama: public yapıcı, topla, toString.
  • Temsil: private int pay, payda; yapıcı kesri sadeleştirir.
  • Uygulama: metot gövdeleri ve gizli ebob yardımcısı (Öklid algoritması).
  • topla mevcut nesneyi değiştirmez, yeni bir nesne döndürür.

a = new RasyonelSayi(8, 10), b = new RasyonelSayi(2, 3); println(a) ve println(a.topla(b)):

Çıktı
4/5
22/15

Özet

Özet

KavramÖzü
Sınıf / nesneSınıf taslaktır; nesne new ile üretilen örneğidir.
YapıcıSınıfla aynı ad, dönüş türü yok; yazılmazsa varsayılan yapıcı eklenir.
Örnek / static üyeÖrnek alanı her nesnede ayrı; static alan sınıfta tek ve ortak.
Başlatıcılarstatic { } bir kez; { } her nesnede, yapıcı gövdesinden önce.
Erişim ve gizlemeNitelikler private; get/set ile kontrollü erişim.
ReferansDeğişken nesneyi değil referansı tutar; atama referansı kopyalar.
thisMetodun çağrıldığı nesne; static metotta yok.
== / equalsAynı nesne mi? / aynı içerik mi?
Wrapperint ↔ Integer: autoboxing ve unboxing.
record / enumDeğişmez veri sınıfı / sabit değer kümesi.
İç sınıflarStatik, üye, yerel, anonim.

Özet

Sık Yapılan Hatalar (1)

Örnek metodu main'den nesnesiz çağırmakerror: non-static method selamVer() cannot be referenced from a static context Önce nesne oluşturun (new Selam().selamVer()) ya da metot gerçekten nesneye bağlı değilse static yapın.
Yapıcıya void yazmakerror: constructor Hata1 in class Hata1 cannot be applied to given types; public void Hata1(String m) yapıcı değil, sıradan metottur. Yapıcının dönüş türü olmaz.
Yalnızca parametreli yapıcı varken new Urun()error: constructor Urun in class Urun cannot be applied to given types; Bir yapıcı yazınca varsayılan yapıcı eklenmez; gerekiyorsa parametresiz yapıcıyı da yazın.
new unutmakerror: cannot find symbol symbol: method Urun(String)Nesne oluşturmak için new Urun("Kalem") yazılmalıdır.

Özet

Sık Yapılan Hatalar (2)

private alana dışarıdan erişmekerror: hesapBakiyesi has private access in BankaHesabi Sınıfın get/set metotlarını kullanın.
static metotta thiserror: non-static variable this cannot be referenced from a static context Static metodun bir nesnesi yoktur.
this unutmak (gölgeleme)ad = ad; // derlenir, nitelik null kalırParametre niteliği gölgeler; this.ad = ad; yazın.
Yalnız dönüş türü farklı aşırı yüklemeerror: method topla(int,int) is already defined in class Hesap2 Parametre listesi farklı olmalıdır.

Özet

Sık Yapılan Hatalar (3)

Nesneleri == ile karşılaştırmakk1 == k2 // falseİçerik için equals() kullanın; String ve wrapper'lar dahil.
null referansı kullanmakNullPointerExceptionNesne oluşturulmadan veya null atandıktan sonra metot çağrılamaz; önce kontrol edin.
Record alanını değiştirmeye çalışmakerror: x has private access in Nokta Record değişmezdir; yeni değerle yeni bir nesne oluşturun.
Üye iç sınıfı static main'de oluşturmakerror: non-static variable this cannot be referenced from a static context outer.new MemberInner() yazın ya da iç sınıfı static yapın.

Özet

Örnek Problemler (1)

Problem 1. Ne yazdırır?

class Sayac {
  static int toplam = 0;
  int adet = 0;
  void arttir() { toplam++; adet++; }
}
public class Problem1 {
  public static void main(String[] args) {
    Sayac a = new Sayac(), b = new Sayac();
    a.arttir(); a.arttir(); b.arttir();
    System.out.print(a.adet + " " + b.adet);
    System.out.println(" " + Sayac.toplam);
  }
}

Problem 2. Ne yazdırır?

class Kutu { int deger; }
public class Problem2 {
  public static void main(String[] args) {
    Kutu k1 = new Kutu();
    k1.deger = 5;
    Kutu k2 = k1;
    k2.deger = 9;
    Kutu k3 = new Kutu();
    k3.deger = 9;
    System.out.println(k1.deger);
    System.out.println(k1 == k2);
    System.out.println(k2 == k3);
  }
}
Cevapları göster
  1. 2 1 3. adet her nesnede ayrıdır (a: 2, b: 1); toplam static olduğu için üç çağrının hepsini sayar: 3.
  2. 9, true, false. k2 = k1 aynı nesneyi gösterir: k2.deger = 9 sonrası k1.deger da 9. k3 ayrı nesnedir; değerleri eşit olsa da == false.

Özet

Örnek Problemler (2)

Problem 3. Ne yazdırır?

class A {
  static { System.out.print("S"); }
  { System.out.print("I"); }
  A() { System.out.print("C"); }
}
public class Problem3 {
  public static void main(String[] args) {
    System.out.print("M");
    new A();
    new A();
    System.out.println();
  }
}

Problem 4. Ne yazdırır?

class Kutu { int deger; }
public class Problem4 {
  static void degistir(Kutu k) {
    k.deger = 100;
    k = new Kutu();
    k.deger = 7;
  }
  public static void main(String[] args) {
    Kutu x = new Kutu();
    x.deger = 1;
    degistir(x);
    System.out.println(x.deger);
  }
}
Cevapları göster
  1. MSICIC. Önce main "M" yazar. A sınıfı ilk new A()'da yüklenir: static blok bir kez (S); sonra her nesne için örnek başlatıcı (I) ve yapıcı (C).
  2. 100. degistir, referansın kopyasını alır: k.deger = 100 asıl nesneyi değiştirir; k = new Kutu() yalnızca yerel kopyayı başka bir nesneye yöneltir, x etkilenmez.

Özet

Örnek Problemler (3)

Problem 5. Ne yazdırır?

record Para(int lira) { }
public class Problem5 {
  public static void main(String[] args) {
    Para p1 = new Para(10);
    Para p2 = new Para(10);
    Integer i1 = 1000, i2 = 1000;
    System.out.println(p1.equals(p2));
    System.out.println(p1 == p2);
    System.out.println(i1.equals(i2));
    System.out.println(p1);
  }
}

Problem 6. Ne yazdırır?

class Nokta {
  int x, y;
  Nokta(int x, int y) {
    this.x = x;
    this.y = y;
  }
}
public class Problem6 {
  public static void main(String[] args) {
    Nokta a = new Nokta(1, 2);
    Nokta b = new Nokta(1, 2);
    System.out.println(a.equals(b));
    System.out.println(a.x == b.x);
  }
}
Cevapları göster
  1. true / false / true / Para[lira=10]. Record'ın equals'ı içeriği, == referansı karşılaştırır; Integer için equals her zaman güvenlidir.
  2. false / true. equals yazılmamış: Object'inki referans karşılaştırır. a.x == b.x iki int değerdir.

Özet

Alıştırmalar

  1. Kitap sınıfı: private baslik, yazar, sayfaSayisi; üç parametreli yapıcı, get metotları ve toString().
  2. Kitap'a static toplamKitapSayisi sayacı ve yalnızca pozitif değeri kabul eden setSayfaSayisi ekleyin.
  3. Daire sınıfı: yaricap, alan(), cevre(). new Daire(3) için iki basamakla yazdırın.
  4. Mevsim enum'unun değerlerini sıra numaralarıyla yazdırın.
  5. OgrenciKaydi(String ad, int numara) record'unu yazıp bir nesnesini yazdırın.
Cevaplar / ipuçları
  1. this.baslik = baslik; ...; toString() → Nutuk (Atatürk, 600 s.)
  2. Yapıcıda toplamKitapSayisi++;, setter'da if (sayfaSayisi > 0) .... −5 sayfalı ikinci kitapta sayfa 0 kalır, sayaç 2: 0 2
  3. Math.PI * yaricap * yaricap, 2 * Math.PI * yaricap; printf("%.2f %.2f%n", ...) → 28,27 18,85 (Türkçe yerel ayarda virgül).
  4. for (Mevsim m : Mevsim.values()) → 0:ILKBAHAR 1:YAZ 2:SONBAHAR 3:KIS
  5. record OgrenciKaydi(String ad, int numara) { } → OgrenciKaydi[ad=Ali, numara=7]

Özet

Kaynaklar

  • Oracle, The Java Tutorials: "Classes and Objects", "Nested Classes", "Enum Types", "Record Classes", "Autoboxing and Unboxing".
  • J. Gosling ve diğ., The Java Language Specification, Java SE 21 Edition (Bölüm 8 Classes: 8.3 Fields, 8.6–8.7 Initializers, 8.8 Constructors, 8.9 Enum, 8.10 Record).
  • P. Deitel ve H. Deitel, Java: How to Program, Early Objects, 11. baskı, Pearson, 2017 (Bölüm 3 ve 8: Classes and Objects).
  • K. Sierra ve B. Bates, Head First Java, 3. baskı, O'Reilly, 2022.
  • C. S. Horstmann, Core Java, Volume I: Fundamentals, 12. baskı, 2022 (Bölüm 4: Objects and Classes).
  • A. B. Downey ve C. Mayfield, Think Java, 2. baskı, O'Reilly, 2019 (Bölüm 10–11).
  • J. Bloch, Effective Java, 3. baskı, Addison-Wesley, 2018 (equals, hashCode, toString maddeleri).

Son

Bölüm 4: Nesne ve Sınıflar
Sonraki bölüm: Bölüm 4: Sarmalama
1 / 1 Sercan KÜLCÜ, Tüm hakları saklıdır.