Çok Biçimlilik (Polymorphism)

Gün 2: Nesne Yönelimli Programlama (OOP) | Virtual metodlar, upcasting, $cast ile downcasting

Kaynak Kod

// =============================================================================
// GUN 2 - Konu 6: Cok Bicimlilik (Polymorphism) ve Sanal (Virtual) Metodlar
// =============================================================================

class Animal;
  string name;
  int    age;

  function new(string name, int age);
    this.name = name;
    this.age  = age;
  endfunction

  // virtual: Alt siniflarda override edilebilir
  virtual function string speak();
    return "...";
  endfunction

  virtual function void display();
    $display("  [%s] Isim: %s, Yas: %0d, Ses: %s",
             get_type(), name, age, speak());
  endfunction

  virtual function string get_type();
    return "Animal";
  endfunction
endclass

class Dog extends Animal;
  string breed;
  
  function new(string name, int age, string breed = "Mixed");
    super.new(name, age);
    this.breed = breed;
  endfunction

  virtual function string speak();
    return "Hav hav!";
  endfunction

  virtual function string get_type();
    return "Dog";
  endfunction

  virtual function void display();
    super.display();
    $display("         Cins: %s", breed);
  endfunction
endclass

class Cat extends Animal;
  bit is_indoor;

  function new(string name, int age, bit indoor = 1);
    super.new(name, age);
    this.is_indoor = indoor;
  endfunction

  virtual function string speak();
    return "Miyav!";
  endfunction

  virtual function string get_type();
    return "Cat";
  endfunction

  virtual function void display();
    super.display();
    $display("         Ev kedisi: %s", is_indoor ? "Evet" : "Hayir");
  endfunction
endclass

class Parrot extends Animal;
  string vocabulary [$];

  function new(string name, int age);
    super.new(name, age);
  endfunction

  function void learn_word(string word);
    vocabulary.push_back(word);
  endfunction

  virtual function string speak();
    if (vocabulary.size() > 0) begin
      int idx = $urandom % vocabulary.size();
      return vocabulary[idx];
    end
    return "Cik cik!";
  endfunction

  virtual function string get_type();
    return "Parrot";
  endfunction
endclass

module polymorphism;
  initial begin
    // Ust sinif dizisi ile tum hayvanlari tutma (Polimorfizm)
    Animal animals [4];
    Dog    d;
    Cat    c;
    Parrot p;

    $display("=== Polimorfizm (Polymorphism) ===\n");

    // --- Nesneler olustur ---
    d = new("Karabas", 3, "Golden Retriever");
    c = new("Tekir", 2, 0);
    p = new("Papagan", 5);
    p.learn_word("Merhaba!");
    p.learn_word("Gunaydin!");
    p.learn_word("Nasilsin?");

    // --- Polimorfik dizi ---
    animals[0] = new("Bilinmeyen", 0);  // Base
    animals[1] = d;                      // Dog -> Animal (upcasting)
    animals[2] = c;                      // Cat -> Animal
    animals[3] = p;                      // Parrot -> Animal

    // --- virtual metod cagrilari ---
    $display("--- Polimorfik display() ---");
    foreach (animals[i]) begin
      $display("\n  Hayvan #%0d:", i);
      animals[i].display();  // Her nesne kendi override'ini calistirir
    end

    // --- $cast ile downcasting ---
    $display("\n--- $cast ile Downcasting ---");
    begin
      Animal a_ref = d;  // Dog nesnesi, Animal referansi
      Dog    d_ref;
      
      // Guvenli donusum
      if ($cast(d_ref, a_ref)) begin
        $display("  Cast basarili! Cins: %s", d_ref.breed);
      end else begin
        $display("  Cast basarisiz!");
      end

      // Yanlis cast denemesi
      a_ref = c;  // Cat nesnesi
      if (!$cast(d_ref, a_ref))
        $display("  Cat -> Dog cast basarisiz (beklenen)");
    end

    // --- Polimorfik fonksiyon ---
    $display("\n--- Polimorfik Fonksiyon ---");
    begin
      foreach (animals[i]) begin
        make_speak(animals[i]);
      end
    end

    $display("\n=== Polimorfizm Sonu ===");
    $finish;
  end

  // Herhangi bir Animal alt sinifini kabul eder
  function void make_speak(Animal a);
    $display("  %s diyor: %s", a.name, a.speak());
  endfunction
endmodule