Ruby Günlüğü – Gün 3

Nesne Tabanlı Programlama

Öncelikle Ruby pure-object-oriented bir dil olduğu için, nesne tabanlı programlama hakkında bir kaç noktaya değinmek gerekir, aksi halde ileri ki konularda nesne, sınıf, fonksiyon gibi kavramlar karışacaktır. Ben daha önce çok derinlemesine olmasa bile bir python tecrübem olduğu için ve bu sorunları python çalışırken yaşamış olduğum için, bi kez tekrarlamakta fayda görüyorum.

* OOP kullanmak zorunlu değildir, ama bilinmesi gerekir ve kullanılsa iyi olur. Neden mi? “Nesne ve Sınıflarla Birlikte Ruby – 2” başlığında açıkladım.

Konuya devam etmeden önce şu yazıları okumak faydalı olacaktır :

  1. http://cygm.meb.gov.tr/modulerprogramlar/kursprogramlari/bilisim/moduller/nesnetabanliprogramlama1.pdf
  2. http://www.istihza.com/py2/nesne.html
  3. http://www.be.itu.edu.tr/~e.fatih.yetkin/sunum/python3.pdf
  4. http://enginyoyen.com/blog/tr/nesne-tabanli-programlamaoop-nedir

Nesne ve Sınıflarla Birlikte Ruby

Ruby’nin bir OOP dili olduğunu biliyor, bunu en kısa şekilde, Ruby programlarının gerçek hayatımızda ki konsept kavramlarını tanımlayabildiğini ve yönetebildiğini söyleyerek özetleyebiliriz. Ruby programı, insanlar, kutular, biletler, haritalar gibi çalışmak istediğimiz birçok konsepti içerebilir. Ruby OOP dili olması sebebi ile, oluşturduğumuz bu konsepler arasında ilişki kurabilir.

Konseptlere birazdan, sınıf ismini vereceğiz.

Örnek vermek gerekirse, spor müsabakaları için bir bilet sistemi programı kodlamayı düşünüyoruz. Elimiz de temel ve ortak olarak insan, bilet, yer, etkinlik gibi konseptler var. Bu konseptleri iki ayrı etkinlik için kullanabiliriz. Şampiyonlar ligi finali içinde bunları kullanmamız gerekli, üniversiteler arası basketbol turnuvası içinde, işte Ruby’de ilişkilendirmeler kurarak farklı etkinlikler için belirli konseptleri tekrar tekrar hazırlamamıza gerek yok.

Daha önce ki yazıda örnek olarak bir insan oluşturmuş ve ilişkilere göz atmıştık, şimdi OOP bilgisi ile o yazıyı okursanız daha net olacaktır.

Hatırlamak gerekirse ;

Normal bir insan, temel olarak isim-yaş-cinsiyet gibi özelliklere sahiptir. “Class Insan” ile bir insan konsepti tanımladık.

“attr”nin attribute (özellik) manasına geldiğini söylemiştim. “accessor” ise en kaba manasıyla, bak Ruby programı ! Bu tanımladığım özellikler var ya, işte onları istediğim zaman atayabilmemi ve istediğim zaman değiştirebilmemi sağlayabilecek şekilde tanımla demek oluyor.

Sınıfları temel olarak, gerçek hayatta ki konseptler için kullanabileceğimizi söyledik, nesneler ise sınıflar üzerinde ki birer elemandır. Örneğin “insan” bir sınıf ise “serhat” bir nesnedir gibi.

Veya “araba” bir sınıftır, “yarış arabası” ve “jip” ise bir nesnedir, yarış arabasının mavi renk olmasını onun bir özelliği (attribute) olarak örnekleyebiliriz.

ile “Insan” sınıfına ait yeni bir nesne oluşturduk. insan1 nesnesi burada bir yer tutucudur, yani diğer bir tabirle değişkendir. Bellek içerisinde insan1’i tutar ve istediğimiz zaman kullanabilmemizi sağlar.

Değişken’ler mantığını en kolay anlayabildiğimiz terimlerden, özellikle matematik ile biraz olsun uğraşmış biri iseniz değişkenleri çok kolay anlayabilirsiniz. Bir matematik sorusunda “x=5” ile aslında x’değişkenini 5’e eşitlemiş oluyor, yaptığımız şey x isminde bir değişken oluşturmak ve bunu 5 değerine eşitlemek.

Bu örneklemeyi matematik-programlama anlamında ayırmak için genellikle x=x+1 örneği kullanılır.

Matematiksel olarak bu örneğe yaklaşında 0=1 sonucu çıkmakta ve bu tanımsızlık demektir, ancak programlama için konuşursak bu ifade doğrudur. Programın başında x’i x=5 ile 5’e eşitlemiş olalım, bir sonra ki satırda x=x+1 ile x’i değiştirdiğimizi ifade ediyoruz. x önceden 5’ti, artık 1 ekledik ve şuan 6 oldu. Adı üstünde “değişken” yani her an değişebilir.

Değişkenler, sınıflar gibi kalıcı bilgi tutmaz, daha geçicidirler. Program içerisinde sürekli değiştireceğimiz ve oynayacağımız bir veriyi değişken olarak tanımlamak bize esneklik kazandırır.

Nesne ve Sınıflarla Birlikte Ruby – 2

Başlığı 2’ye böldüm çünkü, önce ki satırları tam olarak kavrayamadıysanız ve aklınızda soru işaretleri varsa önce bunları çözmeniz gerekmekte, aksi halde yazının geri kalanı ezberden öte geçmeyecektir.

Şimdi 3 ayrı sınıf tanımlayalım. Bunlar; “Kedi”, “Köpek” ve “Yılan” olsun.

Bu şekilde 3 ayrı hayvan için sınıf tanımlamak herhangi bir sorun doğurmaz, kodumuz hatasız işler, bu sınıflara ailt hayvanlar oluşturabilir, bu hayvanlara tanımladığımız özellikleri atayabiliriz vs.

Ancak bu şekilde sınıf tanımlaması yaptığımız taktirde OOP nimetlerinden faydalanmıyoruz demektir. OOP’in temel yapı taşlarından biri olan “miras” sistemini bu sınıf tanımlamasında hiç kullanmadık. Oysa ki 3 ayrı hayvan var ve belirttiğimiz özellikler de tamamen aynı. Boşu boşuna tekrar tekrar isim, yaş, cinsiyet ve renk özelliklerini tanımlamış olduk.

3 sınıfımızda daha genel, ortak bir özelliğe sahip. Üç sınıfımızda birer hayvan. O halde “Hayvanlar” isminde daha genel bir sınıf tanımlayıp, buna ait özellikleri Kedi, Köpek ve Yılan için kullanabiliriz.

* Kod içerisinde gördüğünüz & ile başlayan şekiller “<” ifadesidir, scriptten kaynaklanan bir durum yüzünden bu şekilde çıkmakta. Karakter setleriyle ilgili bir sorun var, sanırsam. Bunlar neymiş, neyin nesiymiş diyenler şurdan bakabilir : http://msdn.microsoft.com/en-us/library/ms537495.aspx

Kedi, Köpek ve Yılan’ın “Hayvanlar” sınıfın özelliklerini miras alma durumunu “<” işareti ile sağladık. Bu sayede her seferinde isim, yaş, cinsiyet ve renk özelliklerini belirtme zorunluluğundan kurtulduk.

Sorulması gereken güzel soru : Peki her bir hayvanın, sadece kendine has özelliklerini, bu yapıyı bozmadan tanımlamak istesek? Örneğin tüm bunların dışında, kedi için birde kedinin cinsini tanımlayabilir miyiz? Van kedisi gibi?

Elbette, zaten bunu yapamasaydık, OOP’nin ne anlamı kalırdı ki? Şimdi bu nasıl yapılıyor onu görelim örnek üzerinde ;

Gördüğünüz gibi kedi sınıfının altında birde “kedicinsi” özelliği tanımladık. Bu özellik sadece kediler için geçerli, yılan ve köpek hala diğer özellikleri “hayvanlar” sınıfından miras alıyor ve kedi de aynı şekilde ancak, kedinin artı olarak birde “kedicinsi” özelliği var.

Ruby ve Metodlar

Şimdi, oluşturduğumuz bu hayvanlara (siz birer tane oluşturdunuz ve denediniz sayıyorum) bazı işler yaptıralım. Bir nesneye yaptırdığımız işleri method veya fonksiyon olarak ifade edebiliriz. Örneğin köpeğimize bir havlama işi yaptırtabiliriz.

“def” yani “define” bloğunu yine end ile kapattığımıza dikkat etmişsinizdir. Blokları daima end ile kapatmaktayız, yoksa programımız bizim bloğu sürdürmek mi yoksa bitirmek mi istediğimizi anlayamaz.

Sorulması gereken güzel soru : Bütün hayvanlar için ortak olan bir eylem yok mu peki? Eğer varsa bunu nasıl tanımlarız?

Örneğin bütün hayvanlar için ortak bir eylem düşünelim. Aklıma daha iyi bir örnek gelmediği için bütün bu hayvanlara “saldırma” eylemi yaptırtmak istesek? Biz bunları programda çağırınca bize kızıp saldırsalar? (:

O halde bu kod parçamızı ana sınıf içerisine yazmalıyız, yani “class Hayvanlar” ile tanımladığımız blok içerisine.

Tüm örnekleri tek bir uygulama içerisinde görelim o halde :

Bu günlük bu kadar, öğrendikçe yazmayada devam edeceğim.

Mustafa Serhat Dündar

Leave a Reply