Neler yeni

Yazılım Forum

Tüm özelliklerimize erişmek için şimdi bize katılın. Kayıt olduktan ve giriş yaptıktan sonra konu oluşturabilecek, mevcut konulara yanıt gönderebilecek, itibar kazanabilecek, özel mesajlaşmaya erişebilecek ve çok daha fazlasını yapabileceksiniz! Bu hizmetlerimiz ise tamamen ücretsiz ve kurallara uyulduğu sürece sınırsızdır, o zaman ne bekliyorsunuz? Hadi, sizde aramıza katılın!

Ruby'de Nesne Yönelimli Programlamanın Temelleri: Sınıflar ve Nesneler

Giriş: Nesne Yönelimli Programlamaya Genel Bakış

Ruby, tam anlamıyla nesne yönelimli bir programlama dilidir. Bu, Ruby'deki her şeyin – sayılar, dizeler, hatta true ve false değerleri bile – aslında birer nesne olduğu anlamına gelir. Nesne Yönelimli Programlama (NYP veya İngilizce adıyla OOP - Object-Oriented Programming), yazılım tasarımına bir paradigma sunar. Bu paradigma, gerçek dünyadaki varlıkları ve kavramları modellemek için 'nesneler' adı verilen soyut veri yapılarını kullanır. NYP'nin temel sütunları arasında enkapsülasyon, kalıtım ve çok biçimlilik (polimorfizm) bulunur. Ruby'de bu kavramlar, özellikle sınıflar ve nesneler aracılığıyla hayata geçirilir. Bu rehberde, Ruby'deki sınıfların ve nesnelerin derinliklerine inecek, nasıl çalıştıklarını, neden bu kadar önemli olduklarını ve günlük programlama pratiklerinizde onlardan en iyi şekilde nasıl faydalanacağınızı ayrıntılı bir şekilde inceleyeceğiz.

NYP, karmaşık sistemleri daha yönetilebilir, modüler ve anlaşılır hale getirme amacı güder. Bir programı nesneler etrafında organize etmek, kodun yeniden kullanılabilirliğini artırır, bakımı kolaylaştırır ve hataların izini sürmeyi basitleştirir. Ruby'nin bu felsefeyi benimsemesi, dili hem güçlü hem de öğrenmesi keyifli bir hale getirir.

Sınıflar: Nesnelerin Planı

Bir sınıf, tıpkı bir mimarın bina inşa etmeden önce çizdiği bir plan veya kalıp gibidir. Tek başına bir sınıf, programınızda somut bir şey yapmaz; ancak ondan oluşturulacak nesnelerin özelliklerini (veri) ve davranışlarını (metotlar) tanımlar. Ruby'de bir sınıf, `class` anahtar kelimesi kullanılarak tanımlanır.

Ruby:
class Ogrenci
  # Sınıfın tanımı buraya gelir
end

Yukarıdaki örnekte, 'Ogrenci' adında boş bir sınıf tanımladık. Bir sınıfın içinde, o sınıftan oluşturulacak her nesnenin sahip olacağı verileri ve metotları belirtiriz.

Örnek Metotları (Instance Methods):

Nesneler, kendi üzerlerinde çalıştırılabilecek metotlara sahiptir. Bunlar genellikle örnek metotları olarak adlandırılır çünkü her bir sınıf örneği (nesne) bu metotlara erişebilir. Metotlar, nesnenin gerçekleştirebileceği eylemleri veya davranışları tanımlar.

Ruby:
class Ogrenci
  def selamla
    "Merhaba, ben bir öğrenciyim!"
  end
end

İlklendirme Metodu: initialize

Ruby'de, bir nesne oluşturulduğunda otomatik olarak çağrılan özel bir metot vardır: `initialize`. Bu metot, nesnenin ilk durumunu ayarlamak için kullanılır ve genellikle kurucu metot (constructor) olarak adlandırılır. `initialize` metodunda tanımlanan parametreler, nesne oluşturulurken `new` metoduna iletilir.

Ruby:
class Ogrenci
  def initialize(ad, numara)
    @ad = ad         # Örnek değişkeni
    @numara = numara # Örnek değişkeni
  end

  def bilgileri_goster
    "Ad: #{@ad}, Numara: #{@numara}"
  end
end

Yukarıdaki örnekte, `@ad` ve `@numara` örnek değişkenleridir. Bir örnek değişkeni, o sınıftan oluşturulan her bir nesneye özgüdür. Her öğrencinin kendi adı ve numarası olacaktır.

Erişimciler (Accessors): attr_reader, attr_writer, attr_accessor

Örnek değişkenlerine doğrudan erişim sağlamak iyi bir uygulama değildir (enkapsülasyon ilkesi). Bunun yerine, bu değişkenlere erişim veya atama yapmak için metotlar (erişimciler) kullanırız. Ruby, bu tür metotları hızlıca oluşturmak için `attr_reader`, `attr_writer` ve `attr_accessor` makrolarını sağlar.


  • [li]`attr_reader`: Sadece okuma (get) metodu oluşturur.[/li]
    [li]`attr_writer`: Sadece yazma (set) metodu oluşturur.[/li]
    [li]`attr_accessor`: Hem okuma hem de yazma (get ve set) metotları oluşturur.[/li]

Ruby:
class Ogrenci
  attr_reader :ad          # Okuma metodu Ogrenci#ad oluşturur
  attr_writer :numara      # Yazma metodu Ogrenci#numara= oluşturur
  attr_accessor :sinif     # Okuma ve yazma metotları Ogrenci#sinif, Ogrenci#sinif= oluşturur

  def initialize(ad, numara, sinif)
    @ad = ad
    @numara = numara
    @sinif = sinif
  end

  def bilgileri_goster
    "Ad: #{@ad}, Numara: #{@numara}, Sınıf: #{@sinif}"
  end
end

Artık bir öğrenci nesnesinin adına `ogrenci.ad` ile erişebilir ve sınıfını `ogrenci.sinif = "10B"` ile değiştirebiliriz.

Sınıf Metotları (Class Methods):

Sınıf metotları, sınıfın kendisi üzerinde çalışır, tek tek nesneler üzerinde değil. Genellikle belirli bir sınıfa ait genel işlevsellik veya nesne oluşturma alternatif yolları (factory methods) sağlamak için kullanılırlar. Bir sınıf metodu, metodun adının önüne `self.` veya sınıfın adını getirerek tanımlanır.

Ruby:
class Ogrenci
  attr_accessor :ad, :numara, :sinif

  @@toplam_ogrenci_sayisi = 0 # Sınıf değişkeni

  def initialize(ad, numara, sinif)
    @ad = ad
    @numara = numara
    @sinif = sinif
    @@toplam_ogrenci_sayisi += 1 # Her yeni nesne oluşturulduğunda artır
  end

  def self.toplam_sayi
    @@toplam_ogrenci_sayisi
  end

  def self.en_populer_sinif
    # Bu metodun mantığı daha karmaşık olabilir
    "10A"
  end
end

`@@toplam_ogrenci_sayisi` bir sınıf değişkenidir. Örnek değişkenlerinin aksine, sınıf değişkenleri o sınıfın tüm örnekleri tarafından paylaşılır. Tüm öğrenci nesneleri bu tek `@@toplam_ogrenci_sayisi` değişkenini kullanır ve değiştirir.

Nesneler: Sınıfın Somut Halleri

Bir nesne, bir sınıfın somut bir örneğidir. Tıpkı bir bina planından (sınıf) inşa edilen gerçek bir bina (nesne) gibi. Ruby'de bir nesneyi `new` metodunu çağırarak oluşturursunuz.

Ruby:
ogrenci1 = Ogrenci.new("Ali", "123", "9A")
ogrenci2 = Ogrenci.new("Ayşe", "456", "10B")

puts ogrenci1.bilgileri_goster # => "Ad: Ali, Numara: 123, Sınıf: 9A"
puts ogrenci2.bilgileri_goster # => "Ad: Ayşe, Numara: 456, Sınıf: 10B"

puts Ogrenci.toplam_sayi # => 2

Her bir `ogrenci1` ve `ogrenci2` değişkeni, `Ogrenci` sınıfının ayrı birer nesnesini (örneğini) temsil eder. Her biri kendi `@ad`, `@numara` ve `@sinif` değerlerine sahiptir.

self Anahtar Kelimesi:

`self` anahtar kelimesi, mevcut nesneye (örnek metotları içinde) veya mevcut sınıfa (sınıf metotları içinde) referans verir. Genellikle, metotlar içinde örnek değişkenleriyle çakışan lokal değişkenler olduğunda kullanılır veya bir metottan başka bir metodu çağırmak gerektiğinde netlik sağlamak için kullanılır.

Ruby:
class Urun
  attr_accessor :ad, :fiyat

  def initialize(ad, fiyat)
    @ad = ad
    @fiyat = fiyat
  end

  def indirim_uygula(oran)
    self.fiyat = self.fiyat * (1 - oran) # self.fiyat, attr_accessor tarafından oluşturulan metodu çağırır
  end

  def kendini_tanit
    "Ben bir #{self.class} nesnesiyim. Adım #{self.ad}."
  end
end

urun = Urun.new("Klavye", 200)
puts urun.kendini_tanit # => "Ben bir Urun nesnesiyim. Adım Klavye."
urun.indirim_uygula(0.10)
puts urun.fiyat # => 180.0

Kalıtım (Inheritance): Davranışları Genişletme

Kalıtım, bir sınıfın (alt sınıf veya çocuk sınıf), başka bir sınıfın (üst sınıf veya ebeveyn sınıf) özelliklerini ve davranışlarını miras almasına olanak tanıyan bir NYP ilkesidir. Bu, kodun yeniden kullanılabilirliğini artırır ve hiyerarşik bir yapı oluşturur. Ruby'de `<` sembolü ile kalıtım belirtilir.

Ruby:
class Kisi
  attr_accessor :ad, :soyad

  def initialize(ad, soyad)
    @ad = ad
    @soyad = soyad
  end

  def tam_ad
    "#{@ad} #{@soyad}"
  end
end

class Ogrenci < Kisi # Ogrenci, Kisi'den miras alır
  attr_accessor :okul_no

  def initialize(ad, soyad, okul_no)
    super(ad, soyad) # Üst sınıfın initialize metodunu çağırır
    @okul_no = okul_no
  end

  def bilgileri_goster
    "#{tam_ad} (Okul No: #{@okul_no})"
  end
end

class Ogretmen < Kisi # Ogretmen de Kisi'den miras alır
  attr_accessor :brans

  def initialize(ad, soyad, brans)
    super(ad, soyad)
    @brans = brans
  end

  def bilgileri_goster
    "#{tam_ad} (Branş: #{@brans})"
  end
end

ogrenci = Ogrenci.new("Burak", "Yılmaz", "5005")
ogretmen = Ogretmen.new("Zeynep", "Demir", "Matematik")

puts ogrenci.bilgileri_goster  # => "Burak Yılmaz (Okul No: 5005)"
puts ogretmen.bilgileri_goster # => "Zeynep Demir (Branş: Matematik)"

super Anahtar Kelimesi:

Alt sınıfta `super` anahtar kelimesi, üst sınıfın aynı isimdeki metodunu çağırmak için kullanılır. Özellikle `initialize` metodu içinde, üst sınıfın başlatma mantığını çalıştırmak için sıkça kullanılır. Parametresiz çağrıldığında, `super` otomatik olarak geçerli metodun tüm parametrelerini üst metoda iletir.

Çok Biçimlilik (Polymorphism): Farklı Nesneler, Aynı Arayüz

Çok biçimlilik, farklı sınıflara ait nesnelerin aynı arayüzü paylaşabilmesi ve aynı metoda farklı şekillerde yanıt verebilmesi yeteneğidir. Ruby'de bu, temel olarak metot geçersiz kılma (method overriding) ve duck typing ile sağlanır.

Metot Geçersiz Kılma:

Bir alt sınıf, üst sınıfta tanımlanmış bir metodu kendi özel uygulamasıyla yeniden tanımlayabilir. Yukarıdaki `bilgileri_goster` metodu bu duruma güzel bir örnektir. Hem `Ogrenci` hem de `Ogretmen` sınıfları `Kisi` sınıfında olmayan kendi `bilgileri_goster` metotlarına sahiptirler. Eğer alt sınıflarda `bilgileri_goster` tanımlanmasaydı, üst sınıfın metodu çağrılırdı.

Ruby:
class Hayvan
  def konus
    "(Ses çıkarır)"
  end
end

class Kedi < Hayvan
  def konus
    "Miyav!"
  end
end

class Kopek < Hayvan
  def konus
    "Hav hav!"
  end
end

dizi = [Kedi.new, Kopek.new, Hayvan.new]

dizi.each do |hayvan|
  puts hayvan.konus
end
# Çıktı:
# Miyav!
# Hav hav!
# (Ses çıkarır)

Bu örnekte, üç farklı nesne (`Kedi`, `Kopek`, `Hayvan`) aynı `konus` metodunu çağırıyor ancak her biri kendi türüne özgü bir yanıt veriyor. Bu, çok biçimliliğin gücünü gösterir.

Duck Typing:

Ruby'de, bir nesnenin belirli bir sınıfın örneği olup olmadığına bakılmaksızın, belirli bir metodu yanıtlayıp yanıtlamadığına odaklanılır. "Eğer ördek gibi yürüyorsa ve ördek gibi vakvaklıyorsa, o bir ördektir." Bu felsefe, Ruby'deki esnekliği artırır ve kalıtım hiyerarşileri yerine arayüzlere odaklanmayı teşvik eder.

"Eğer ördek gibi yürüyorsa ve ördek gibi vakvaklıyorsa, o bir ördektir."

Enkapsülasyon: Veri Saklama ve Koruma

Enkapsülasyon, bir nesnenin verilerini (örnek değişkenleri) ve bu veriler üzerinde çalışan metotları tek bir birim içinde bir araya getirme ve bu verilere dışarıdan doğrudan erişimi sınırlama ilkesidir. Bu, nesnenin iç durumunun yanlışlıkla değiştirilmesini önler ve kodun güvenilirliğini artırır. Ruby'de bu, `attr_accessor` gibi erişimciler ve `private` ile `protected` metotlar kullanılarak sağlanır.

private ve protected Metotlar:


  • [li]`private` Metotlar: Sadece tanımlandıkları sınıfın içinde, başka metotlar tarafından çağrılabilirler. Doğrudan alıcı nesne (receiver) belirtilerek çağrılamazlar. Yani `self.metot` şeklinde değil, sadece `metot` şeklinde çağrılırlar.[/li]
    [li]`protected` Metotlar: Tanımlandıkları sınıfın ve alt sınıfların örnekleri tarafından çağrılabilirler. Ancak bu çağrılar sadece kendi sınıfından veya alt sınıflarından bir nesne üzerinden `self` veya başka bir aynı tip nesne üzerinden yapılabilir.[/li]

Ruby:
class Hesap
  def initialize(bakiye)
    @bakiye = bakiye
  end

  def cek(miktar)
    if miktar <= @bakiye
      @bakiye -= miktar
      puts "#{miktar} TL çekildi. Yeni bakiye: #{@bakiye} TL."
    else
      puts "Yetersiz bakiye. Mevcut bakiye: #{@bakiye} TL."
    end
  end

  def goster_bakiye
    gizli_bakiye # Sadece sınıf içinden çağrılabilir
  end

  private

  def gizli_bakiye
    "Mevcut bakiye (gizli): #{@bakiye} TL."
  end
end

hesap = Hesap.new(1000)
hesap.cek(300)
# puts hesap.gizli_bakiye # Hata verecektir: private method `gizli_bakiye' called
puts hesap.goster_bakiye # => Mevcut bakiye (gizli): 700 TL.

Modüller (Modules): Mixin'ler ve Ad Alanları

Ruby'de modüller, sınıflara benzer ancak kendilerinden nesne oluşturulamaz. İki ana amaca hizmet ederler:


  • [li] Mixin'ler (Mixins): Ortak davranışları birden fazla sınıfa karıştırmak (inject) için kullanılırlar. Ruby, çoklu kalıtımı doğrudan desteklemez, ancak modüller bu işlevi mixin'ler aracılığıyla sağlar. Bir modülü bir sınıfa dahil etmek için `include` anahtar kelimesi kullanılır.[/li]
    [li] Ad Alanları (Namespaces): İsim çakışmalarını önlemek ve ilgili sınıfları, metotları ve sabitleri mantıksal olarak gruplandırmak için kullanılırlar.[/li]

Ruby:
module Davranislar
  def kos
    "Koşuyorum!"
  end

  def zipla
    "Zıplıyorum!"
  end
end

class Sporcu
  include Davranislar # Modülü dahil et

  def antrenman_yap
    puts kos
    puts zipla
    "Antrenman bitti."
  end
end

class Kedi
  include Davranislar # Kedi de aynı davranışları kazanır

  def miyavla
    "Miyav!"
  end
end

sporcu = Sporcu.new
kedi = Kedi.new

puts sporcu.antrenman_yap
# Çıktı:
# Koşuyorum!
# Zıplıyorum!
# Antrenman bitti.

puts kedi.kos # => "Koşuyorum!"

Bu örnekte, `Davranislar` modülü sayesinde hem `Sporcu` hem de `Kedi` sınıfları `kos` ve `zipla` metotlarına sahip olur. Bu, kod tekrarını önler ve daha modüler tasarımlar yapmamızı sağlar.

Sonuç: Ruby'de NYP'nin Gücü

Ruby'deki sınıflar ve nesneler, dilin nesne yönelimli doğasının temelini oluşturur. Sınıflar, nesneler için bir şablon görevi görürken, nesneler bu şablonların somutlaşmış halleridir. Kalıtım, çok biçimlilik ve enkapsülasyon gibi NYP ilkeleri, Ruby'nin güçlü ve esnek bir dil olmasını sağlar. Modüller ise bu yapıyı daha da genişleterek kodun yeniden kullanılabilirliğini ve organizasyonunu artırır.

Bu kavramları derinlemesine anlamak, sadece daha iyi Ruby kodları yazmanıza yardımcı olmakla kalmayacak, aynı zamanda genel olarak yazılım mühendisliği prensipleri hakkında daha sağlam bir kavrayış geliştirmenizi sağlayacaktır. Karmaşık sistemleri tasarlarken ve uygularken, sınıfların ve nesnelerin nasıl etkileşim kurduğunu bilmek, karşılaşılan sorunlara daha zarif ve sürdürülebilir çözümler bulmanızı sağlayacaktır. Unutmayın, iyi bir nesne yönelimli tasarım, kodun okunabilirliğini, bakımını ve genişletilebilirliğini doğrudan etkiler.

Daha fazla bilgi için Ruby resmi dokümantasyonunu ziyaret edebilirsiniz.

Bu rehberin, Ruby'deki sınıflar ve nesneler dünyasına girişinizde size yardımcı olduğunu umuyoruz. Pratik yapmaya devam edin ve kod yazmaktan çekinmeyin! Deneyim, en iyi öğretmendir.

"Programlamada en iyi yol, yazmaya devam etmektir." - Anonim

Önemli Hatırlatma:

  • [li]Ruby'de her şey bir nesnedir.[/li]
    [li]Sınıflar, nesnelerin şablonlarıdır.[/li]
    [li]Nesneler, sınıfların örnekleridir.[/li]
    [li]Örnek değişkenleri (`@`) nesneye özgüdür.[/li]
    [li]Sınıf değişkenleri (`@@`) tüm sınıf örnekleri tarafından paylaşılır.[/li]
    [li]Kalıtım (`<`) kodun tekrarını azaltır.[/li]
    [li]Modüller (`include`) çoklu kalıtım benzeri özellikler sağlar ve ad alanları oluşturur.[/li]
 
shape1
shape2
shape3
shape4
shape5
shape6
Üst

Bu web sitenin performansı Hazal Host tarafından sağlanmaktadır.

YazilimForum.com.tr internet sitesi, 5651 sayılı Kanun’un 2. maddesinin 1. fıkrasının (m) bendi ve aynı Kanun’un 5. maddesi kapsamında Yer Sağlayıcı konumundadır. Sitede yer alan içerikler ön onay olmaksızın tamamen kullanıcılar tarafından oluşturulmaktadır.

YazilimForum.com.tr, kullanıcılar tarafından paylaşılan içeriklerin doğruluğunu, güncelliğini veya hukuka uygunluğunu garanti etmez ve içeriklerin kontrolü veya araştırılması ile yükümlü değildir. Kullanıcılar, paylaştıkları içeriklerden tamamen kendileri sorumludur.

Hukuka aykırı içerikleri fark ettiğinizde lütfen bize bildirin: lydexcoding@gmail.com

Sitemiz, kullanıcıların paylaştığı içerik ve bilgileri 6698 sayılı KVKK kapsamında işlemektedir. Kullanıcılar, kişisel verileriyle ilgili haklarını KVKK Politikası sayfasından inceleyebilir.

Sitede yer alan reklamlar veya üçüncü taraf bağlantılar için YazilimForum.com.tr herhangi bir sorumluluk kabul etmez.

Sitemizi kullanarak Forum Kuralları’nı kabul etmiş sayılırsınız.

DMCA.com Protection Status Copyrighted.com Registered & Protected