EDA Playground'da Dene

this ve static

Gün 2: Nesne Yönelimli Programlama (OOP) | this anahtar kelimesi, statik değişkenler ve metodlar

Bu derste iki önemli OOP kavramını öğreneceğiz: nesnenin kendisini ifade eden this anahtar kelimesi ve tüm nesneler arasında ortak olan static değişken ile metodlar. Ayrıca this'i döndürerek metodları zincirleme (method chaining) bağlamayı göreceğiz.

this Anahtar Kelimesi

this, bir metodun içinde o an üzerinde çalışılan nesneyi ifade eder. En sık iki amaçla kullanılır:

  • İsim çakışmasını çözmek: Bir parametre ile özellik aynı ada sahipse, this.id = id ifadesinde this.id nesnenin özelliğini, id ise parametreyi belirtir.
  • Metod zincirleme: Bir metod this'i döndürürse, çağrıları nesne.metot1().metot2() şeklinde art arda bağlayabilirsiniz.

static Değişkenler ve Metodlar

Normalde her nesnenin özelliklerinin kendi kopyası vardır. static olarak işaretlenen bir değişken ise sınıfa aittir; o sınıftan üretilen tüm nesneler arasında tek bir ortak kopya paylaşılır.

  • static değişkenler: Nesne sayısı saymak, toplam istatistik tutmak veya benzersiz kimlik üretmek gibi sınıf düzeyinde durum tutmak için idealdir.
  • static metodlar: Bir nesneye ihtiyaç duymadan, sınıf adı ve :: operatörüyle (Transaction::get_count()) çağrılabilir. Bir static metod yalnızca static üyelere erişebilir, nesneye özgü üyelere erişemez.

Kaynak Kod

// =============================================================================
// GUN 2 - Konu 3: this Anahtar Kelimesi, Statik Degiskenler ve Metodlar
// =============================================================================

class Transaction;
  // Statik degisken: Tum nesneler arasinda paylasilir
  static int count = 0;
  static int total_data = 0;

  // Nesne degiskenleri
  int id;
  int data;
  string name;

  // Constructor: 'this' ile parametre/ozellik ayrimi
  function new(int id, int data, string name = "txn");
    this.id   = id;       // this.id = nesne ozelligi, id = parametre
    this.data = data;
    this.name = name;
    count++;              // Her yeni nesne sayaci artirir
    total_data += data;
  endfunction

  function void display();
    $display("  [%s] id=%0d, data=%0d", this.name, this.id, this.data);
  endfunction

  // Statik metod: Nesne olmadan cagrilabilir
  static function int get_count();
    return count;
  endfunction

  static function int get_total_data();
    return total_data;
  endfunction

  static function void reset_stats();
    count = 0;
    total_data = 0;
  endfunction

  // Zincirleme metod (method chaining benzeri): this dondur
  function Transaction set_data(int data);
    this.data = data;
    total_data += data;
    return this;
  endfunction

  function Transaction set_name(string name);
    this.name = name;
    return this;
  endfunction

endclass

module this_ve_static;
  initial begin
    Transaction t1, t2, t3;

    $display("=== this ve static Kullanimi ===\n");

    // --- Statik: Nesne olusmadan erisim ---
    $display("--- static: Baslangic ---");
    $display("  Nesne sayisi = %0d", Transaction::get_count());

    // --- Nesne olustur ---
    $display("\n--- Nesne Olusturma (this ile) ---");
    t1 = new(1, 100, "paket_A");
    t2 = new(2, 200, "paket_B");
    t3 = new(3, 300, "paket_C");

    t1.display();
    t2.display();
    t3.display();

    // --- set_data ve set_name kullanimi (tek tek) ---
    $display("\n--- set_data ve set_name (tek tek cagri) ---");
    t1.set_data(150);
    t1.set_name("paket_A_guncel");
    t1.display();

    // --- set_data ve set_name kullanimi (zincirleme) ---
    $display("\n--- set_data ve set_name (zincirleme) ---");
    t2.set_name("paket_B_plus").set_data(250);
    t2.display();

    // --- Statik degiskenlere erisim ---
    $display("\n--- static Degiskenler ---");
    $display("  Toplam nesne = %0d", Transaction::get_count());
    $display("  Toplam veri  = %0d", Transaction::get_total_data());
    // Nesne uzerinden de erisilebilir (ayni deger)
    $display("  t1.count     = %0d (statik, tum nesneler ayni)", t1.count);

    // --- Statik reset ---
    $display("\n--- static Reset ---");
    Transaction::reset_stats();
    $display("  Reset sonrasi sayac = %0d", Transaction::get_count());

    // Yeni nesneler
    t1 = new(10, 500);

    // Yeni nesne uzerinde zincirleme setter ornegi
    t1.set_name("reset_sonrasi_t1").set_data(550);
    t1.display();

    t2 = new(20, 600);
    $display("  2 yeni nesne sonrasi sayac = %0d", Transaction::get_count());
    $display("  Toplam veri = %0d", Transaction::get_total_data());

    $display("\n=== this ve static Sonu ===");
    $finish;
  end
endmodule

Kodun Açıklaması

  • Statik değişkenler: static int count ve static int total_data, Transaction sınıfının tüm nesneleri arasında paylaşılır. Her new() çağrısında count++ ile nesne sayısı artar ve total_data += data ile toplam veri birikir.
  • this ile başlatma: Constructor'da this.id = id, this.data = data, this.name = name ifadeleri parametre adlarıyla çakışan özellikleri ayrıştırır.
  • Statik metodlar: get_count(), get_total_data() ve reset_stats() static olduğundan nesne olmadan Transaction::get_count() biçiminde çağrılabilir. Nitekim ilk çağrı, henüz hiç nesne yokken sayacı 0 olarak okur.
  • Method chaining: set_data() ve set_name() metodları, ilgili özelliği güncelledikten sonra return this ile nesnenin kendisini döndürür. Bu sayede t2.set_name("paket_B_plus").set_data(250) gibi zincirleme çağrı mümkün olur.
  • Statik üyeye nesne üzerinden erişim: t1.count ifadesi de aynı paylaşılan değeri verir; statik değişken nesneye özgü olmadığı için tüm nesnelerde aynıdır.
  • reset_stats() etkisi: Statik sayaçlar sıfırlanır; ardından oluşturulan yeni nesneler sayacı tekrar artırmaya baştan başlar.
  • Dikkat - set_data ve total_data: set_data() çağrıldığında total_data += data ile toplam yeniden artırılır. Yani aynı nesnenin verisini değiştirmek toplam istatistiğe tekrar eklenir; bu, istatistiğin nasıl tanımlandığına bağlı bir tasarım davranışıdır.

Önemli Noktalar

  • this, yalnızca bir nesne metodu (non-static) içinde anlamlıdır; static bir metodun içinde this kullanılamaz çünkü ortada belirli bir nesne yoktur.
  • static değişkenler sınıf yüklendiğinde bir kez başlatılır ve nesneler arasında paylaşılır; benzersiz kimlik üretimi veya sayaç gibi global durum için idealdir.
  • static metodlar yalnızca static üyelere erişebilir; nesneye özgü (id, data, name) alanlara erişemezler.
  • Statik üyelere erişmek için sınıf adı ve :: operatörünü kullanmak (Transaction::get_count()), nesne üzerinden erişmekten (t1.count) niyet olarak daha açıktır.
  • Method chaining için her setter'ın return this yapması gerekir; bu kalıp, akıcı ve okunaklı yapılandırma kodu yazmayı sağlar.