2 Temel Bilgiler Bu bölümde Nesne Tabanlı Programlamanın temeli olan Sınıf kavramı ve ilgili bilgiler anlatılacaktır. Konuyu bilenler bu bölümü atlayabilirler. 2.1 Nesne Tabanlı Programlama Günümüzde, Nesne Tabanlı Programlama (NTP), genel amaçlı programcılıkta ulaşılan bir norm haline gelmiştir. C++ ve java ile yaygınlık kazanan Nesne tabanlı Programlama, Perl, Python ve Ruby gibi yeni dillerde yeni gelişim alanları bulmaktadır. Python ve Ruby bir script dilinin hünerleri yanında genel amaçlı NTP’nın programcıya sağladığı üstün niteliklere de sahiptir. Veri tabanı, görsel arayüz, ağ ve web gibi temel uygulama alanlarında etkilidirler. 1995 yılından sonra yaygınlık kazanmaya başlayan Nesne Tabanlı Programlama1 , bir adım daha ileri giderek, 1970 lerde yaratılan soyut veri yapısına değişkenler yanında, o değişkenlerle işlem yapan fonksiyonları da ekledi. Elde edilen yeni veri yapısına (veri tipi) sınıf (class) denilir. Sınıf kavramı kalıtım ve çokbiçemlilik gibi çok önemli iki aracı programlamaya katarken, veri yapılarında ve fonksksiyon adlarında da standartlaşmaya yol açtı. 1 ’Tabanlı’ nitelemesi gereksizdir. Yapılan işe bakılırsa, ’Nesne Programlama’ demek daha doğrudur. BÖLÜM 2. TEMEL BILGILER 8 2.2 Sınıf ve Nesne (class & objects) Sınıf, nesne için bir şablondur (template); nesneler sınıftan üretilir. Sınıf (class) soyut bir veri tipidir. Nesne (object) onun somutlaşan bir cismidir. Bu tanımın kendisi de çok soyut kalıyor. O nedenle örneklerle biraz ayrıntıya inelim. Sınıftan nesne üretmek, bir otomobil fabrikasında tasarımdan otomobil üremeye benzer. Otomobil bir sınıftır. Sınıfın öznitelikleri vardır. Akaryakıtla çalışan motorları, lastik tekerleri, direksiyonları, frenleri vb vardır. Marşa basınca çalışırlar, direksiyonla dönerler, gaza basınca hızlanırlar, frene basınca dururlar . . . . Bunlar otomobilin tasarımında belirtilir. Otomobil sınıfının sayılan öznitelikleri değişkenlerle, eylemleri metotlarla belirlenir. Otomobil sınıfı soyut bir veri yapısıdır. Ama üretilen her otomobil somut bir varlıktır, bir nesnedir. Bir sınıf öznitelikleri ve metotlarıyla soyut bir veri yapısıdır. O nedenle, Nesne Tabanlı Programlama’da (NTP) [Object Oriented Programming - OOP] her sınıf soyut bir veri tipidir (ADT - abstract data type); her veri tipi bir sınıftır. Sınıf, Altsınıf, Üstsınıf Bitkiler çok geniş bir topluluktur. Bu topluluğu büyük bir sınıf olarak alırsak, ağaçlar onun bir alt sınıfıdır. Ağaçlar, bitkiler sınıfının bütün özeliklerine sahip olmak yanında, kendilerine özgü başka özeliklere de sahiptir. Ağaçlar sınıfından meyve-ağaçları sınıfını, onun içinden de, diyelim, elmaağaçları sınıfını seçersek, giderek öğe sayıları azalan ama özelikleri artan içiçe sınıflar elde ederiz: bitkiler ⊃ ağaçlar ⊃ meyve-ağaçları ⊃ elma-ağaçları Yukarıdaki kapsama bağıntısına göre, listede bir sınıfın solundaki sınıfa üstsınıf, sağındaki sınıfa altsınıf denir. 2.3 Ata ve Oğul Yukarıdaki kapsama bağıntısına göre, listede bir sınıfın solunda yer alan sınıflara ata (ancestor), sağında yer alan sınıflara oğul (descendants) denilir. 2.3. ATA VE OĞUL 9 Listenin en sonunda yer alan elma-ağaçları, listenin en başındaki bitkiler sınıfının bütün özeliklerine sahiptir. Dolayısıyla, botanik biliminde bitkilerin özeliklerini öğrenmişsek, onları elma-ağaçları için tekrar öğrenmeye kalkışmak, bize yeni bilgiler kazandırmaz. OOP’de de benzer iş yapılır. Üstsınıfın özelikleri biliniyorsa, altsınıfta onlar tekrarlanmaz. Kalıtım - inheritance Nesne Tabanlı Programlama’da bir sınıfı soyut bir veri yapısı olarak görüp, özeliklerini ortaya koyduktan sonra, onun bir altsınıfında bilinen özelikleri tekrarlamayız. Başka bir deyişle, üstsınıfın bütün özelikleri altsınıfa aynen geçer. Buna kalıtım (inheritance) diyoruz. Üstsınıf ⊃ sınıf ⊃ altsınıf hiyerarşisini genişletirsek, ata ⊃ ... ⊃ oğul sıradüzeni (hierarchy) içinde kalıtımın varlığı ortaya çıkar. Atanın bütün öğeleri oğula kalıtsal geçer. Nesne (object) Kalıtım, OOP’de çok önemli ve yararlıdır. Ama OOP’ye sınıf kavramının girişi yalnızca kalıtım için değildir. Otomobil bir topluluğu belirten cins adıdır. Ama benim otomobilim, otomobil sınıfına ait somut bir nesnedir. Onun plaka numarası, markası, modeli, şasi numarası, rengi, lastik markası, koltuk döşemeleri, maksimum hızı gibi kendine özgü olan ve onu öteki otomobillerden ayıran nitelikleri vardır. O bir cins ya da şablon değil, elle tutulan, gözle görülen bir nesnedir. Diyelim ki, büyük bir inşaat şirketinin tanıtım ofisinde görevliyiz. İnşa halinde 300 konutluk bir siteyi müşterilere tanıtmak için, 300 konutun her birisi için özelikleri ayrı ayrı yazmayız. Onun yerine tek bir listeye 300 konutun ortak özeliklerini yazarız. Bu yazdıklarımız dairelerin ortak özelikleridir. Ama müşteri belirli bir daireye talip olursa, o dairenin hangi katta olduğu, hangi cepheye baktığı gibi belli bir konuta özgü nitelikleri ayrıca söyleyebiliriz. Son söylediklerimiz sınıfa değil, belirli somut bir konuta ait bilgilerdir. OOP’de sınıfa ait bir öğe o sınıftan türemiş bir nesnesidir (instance). Nesne, sınıfın bütün özeliklerine sahiptir. Ortak olanlar yanında kendine BÖLÜM 2. TEMEL BILGILER 10 özgü özelikleri de olabilir. Otomobil örneğine dönersek, marka, model, renk gibi niteliklerin her birisi otomobilin bir özniteliğidir. Her özniteliği (attribute) bir değişkenle belirleriz. Otomobilin yürümesi, hızlanması, dönmesi, durması gibi hareketler onun eylemleridir, davranışlarıdır. Otomobilin her eylemini bir metotla belirleriz. Soyut Veri Yapısı - ADT Genel anlayışa göre, OOP’nin nesneleri (object), gerçek ya da sanal dünyadaki nesneler gibidir. Nesnelerin öznitelikleri (attributes) değişkenlere atanan değerlerle, eylemleri ise metotlarla belirlenir. Kısaca, OOP’de sınıf (class) bir işle ilgili verileri ve metotları içeren bir birimdir. Buna soyut veri yapısı - SVY (abstract data types -ADT) denilir [4]. OOP’de soyut veri yapıları sınıflar (class) ile belirlenir. Sınıf bildiriminin sözdizimi şöyledir: Liste 2.1. 1 6 # sınıf bildirimi c l a s s class_adı #i s t e n i r s e s ı n ı f dökümanı i ç i n y a z ı l a n a ç ı k l a m a ’ [ ilk_deyim 1 ] ... [ son_deyim ] end 2.4 Veri ve Veri Yapıları Veri, bilgisayar programında, komutlar tarafından işlenen bilgilerdir. Bu bilgiler sayı, metin, resim, ses gibi bilgisayar girdisi (input) ya da çıktısı (output) olurlar. Programların çoğu birden çok veri ile işlem yapar. Birden çok veri olduğunda onlara veri toplulukları ya da, Nesne Programlama dillerindeki (OOP) deyimle, veri koleksiyonu (collection) diyeceğiz. Veri koleksiyonları üzerinde farklı işlemler yapılır. O nedenle, veri koleksiyonları anabellekte, üzerlerinde yapılacak işlemlere elverecek biçimde tasarlanmış alanlara yerleştirilir. Bu alanlara "container" denir. Veri yapısı terimi ile "container" terimi eş anlamlıdır. Bu kitapta container yerine veri yapısı, verikabı, veri ambarı ya da, kısaca, ambar, depo terimlerini kullanacağız. Kitap boyunca bu terimlerin eşanlamlı olacaklarını unutmayalım. 2.5. ALGORITMA VE FONKSIYON 11 Ruby veri tipleri, verilerin depo edildiği ambarlardır. Daha açık bir deyişle, bir veri tipi (sınıf), verilerin konulduğu depo ve bu depo üzerinde işlem yapan fonksiyonlardan oluşur. Örneğin, bir veri ambarındaki nesnelerin sıralanması, ambar içinde bir öğenin aranması, ambara yeni öğe eklenmesi ya da var olan bir öğenin ambardan atılması, ambarı başka bir ambara dönüştürme gibi işleri yapan fonksiyonlar vardır. 2.5 Algoritma ve Fonksiyon En genel anlamıyla, algoritma, bir problemi çözmek için izlenen yol, yordam demektir; sonlu sayıda işlemlerden oluşur. Her işlem bir fonksiyondur. Sonlu sayıda fonksiyonun bileşkesi de bir fonksiyondur. Dolayısıyla, her algoritma bir fonksiyondur. Kavramı programcılık açısından düşünürsek, bilgisayar algoritmaları, arka arkaya uygulanan sonlu sayıda bilgisayar komutlarıdır. Ünlü bilgisayar bilimcisi Edsger Dijkstra der ki: Program= Veri Yapıları + Algoritma dır. Program, verileri istenen biçimde işlemek için algoritma kullanır. Algoritmanın verileri işleyebilmesi için, onların anabellekte işlemlere elverecek biçimde bir yerlere konulması gerekir. Anabellekte verilerin konulduğu bu yerlere veri yapıları (data structures) denilir. Bugün algoritma bilim dünyasının farklı dallarında çok kullanılan terimlerden birisidir. Matematik, bilgisayar, kriptoloji gibi dallarda özel konuma sahiptir. Algoritma, bir başlangıç noktasından hareketle, her biri iyi-tanımlı sonlu sayıda ardışık komutlar (işlem) ile önceden öngörülen sonuca ulaşmak demektir. Bunu bilgisayar dilinde söylersek, girdi (input) denilen sonlu sayıda veri, sonlu sayıda komutla işlenip çıktı (output) denilen biçime dönüşür. Girdi’yi çıktı’ya dönüştüren şey bir algoritmadır. Matematik dilinde buna fonksiyon diyoruz. OOP dillerinde fonksiyon ve metot bazen aşanlamlı bazen küçük anlam farklarıyla kullanılır. Ruby kaynaklarında hem fonksiyon hem metot terimleri kullanılır. Bu kitapta, çoğunlukla, metot ve fonksiyon terimlerini eşanlamlı kullanacağız. 2.6 Veri Yapıları Üzerinde İşlemler Her programlama dili verileri tek tek ya da topluluk olarak işleyecek araçlara sahiptir. O araçlar bilgisayar komutu, algoritma, fonksiyon, metot gibi BÖLÜM 2. TEMEL BILGILER 12 adlar alabilir. Her şeyden önce, işlenecek verilerin veri yapısına yani verikabına yerleştirilmesi gerekir. Örneğin, tek bir tamsayı ile iş yapacaksak, o tamsayıyı Integer tipinden bir değişkene değer olarak atarız. Böylece onu anabellekte bir yere koymuş oluruz. Çok sayıda tamsayı ile işlem yapacaksak, onları array ya da daha uygun bir verikabına koyarız. Verileri yerleştirmek için veri yapısını (verikabı) tasarlamak, verileri verikabına yerleştirmek, verikabına yeni veri eklemek, verikabından veri atmak, verikabındaki verileri sıralamak, verikabındaki verilere erişip onlar üzerinde istenen işlemleri yapmak, verikabını başka bir verikabı tipine dönüştürmek vb. işlemler veri toplulukları üzerinde yapılan işlemlere örnektir. Tabii, farklı veri yapıları (verikapları) üzerinde bu işleri yapan algoritmalar (fonksiyon, metot) olmalıdır. Programcı, kullandığı dilde bunları yapan fonksiyonları (algoritma) kendisi yazabileceği gibi, hemen her dilde bu işleri yapan fonksiyonları içeren geniş kütüphanelerden yararlanabilir. Ruby’de gömülü metotların çoğunu Kernel modulünden alırız. 2.7 Veri Yapısı Oluşturma Teknik açıdan veri yapısı, ana bellekte verilerin girileceği bir alandır. Veri yapısı oluşturmak demek, ana bellekte bir alanı o yapıya tahsis etmek demektir. Nesne tabanlı bir dilde, anabellekte bir veri yapısının (verikabı) yaratılması için, önce onun bir sınıf olarak tanımlanması ve ona ait bir nesnenin (object) anabellekte yaratılması gerekir. Bu bağlamda, her veri yapısının bir sınıfa karşılık geldiği görülür. Tabii, bunun tersi de doğrudur. Her veri yapısı bir sınıftır. Başka bir deyişle, Her veri tipi bir sınıftır, her sınıf bir veri tipidir. Bir veri yapısını (verikabı) ötekinden ayıran şey, onun öznitelikleri ve onlara uygulanan metotlardır. Veri yapıları (verikabı) içerecekleri koleksiyon üzerinde yapılacak işlemleri kolaylaştıracak biçimde tasarlanır. Veriler o verikabına yerleşince, bir bakıma o kabın işlevselliğini kazanırlar. Bir veri yapısı (verikabı) üzerinde yapılacak işlemler başka bir veri yapısı üzerinde yapılacak işlemlerden farklıdır. Bir tek veri yapısı (verikabı) her amaca yetmez. Dolayısıyla, farklı amaçlar için farklı veri yapıları (verikapları) oluşturulması doğaldır. 2.8. DERLENEN VE YORUMLANAN DILLER 2.8 13 Derlenen ve Yorumlanan Diller Programlama dillerini farklı bakış açılarına göre sınıflandırmak mümkündür. Bunlardan birisi kaynak programın derlenmesini gerektiren dillerdir. Bunlara derlenen diller denilir. Derlenen dillerin karşıtı ise, yazılan her satırı (komut) anında makina diline çevirip çalıştıran dillerdir. Bunlara yorumlayıcı diller (interpreter) denilir. Derlenen dillerde, kodlar bir kaynak dosyasına topluca yazılır. Sonra makinanın anlayacağı dile çevrilir (derleme, compile). Varsa öndeden derlenmiş başka yardımcı programlarla birleştirilir (make) ve ortaya çıkan son biçim koşturulur (run). C, C++, C#, Java gibi diller bu gruptadır. Yorumlayıcı dillerde ise bir komut satırı yazılır ve o satır makina diline dönüştürülür. Tek satırlık komutu alan yorumlayıcı, o satırın istediği şeyi yapar. Basic, Perl, Python, Ruby, SQL gibi diller bu gruptandır. Derlenen ve yorumlanan diller kendi amaçlarını gerçekleştiriler. Onlar birbirleriyle mukayese edilemezler; dolayısıyla birini ötekine tercih etmek olanaksızdır. Programcı yapacağı iş için kendi amacına en çok uyanı seçer. Yormlayıcı diller, istendiğinde derlenen diller gibi de kullanılabilirler. Başka bir deyişle, yorumlayıcı dillerde büyük programları, derlenen dillerdeki gibi çalıştırmak mümkündür Bunun için kaynak program yazılır ve kaynak programın adı tek satırlık komut imiş gibi yorumlayıcıya verilir. Yorumlayıcı, verilen programdaki kodları sırayla yürütür. IDE ve GUI Günümüzde hem derlenen hem yorumlanan programların kullanımını kolaylaştıran bütünleşik görsel arayüzler (IDE,GUI) vardır. Bunlar programcının hayatını çok kolaylaştırır. Ruby için de bu işi yapan IDE’ler vardır; zamanla yenileri de ortaya çıkacaktır. Bu bölümde, insanın anlayacağı dilde text olarak yazılan komutlardan başlayıp makinaya istenilen işin nasıl yaptırıldığını anlatmak istiyoruz. O nedenle IDE’lere başvurmayacağız. Her işletim sistemi için Ruby ile gelen irb etkileşimli kabuğunu kullanacağız. Bir GUI kullanmaya alışanlar için, başlangıçta zor gibi görünse de bu yöntemin daha öğretici olduğunu göreceksiniz. BÖLÜM 2. TEMEL BILGILER 14 2.9 Hatalar Hayatta yapılacak o kadar çok hata var ki, aynı hatayı yapmakta ısrar etmenin gereği yoktur.— Jean-Paul SARTR — Hata yapmaktan korkan insan, hiçbir şey yapamaz! — Abraham Lincoln — Bilgisayar programlarında üç türlü hata oluşabilir. Sözdizimi (syntax) Hataları : Bunlar en masum hatalardır. Program derlenemez. Dolayısıyla hiç koşmaz. Sonuç olarak, programcısından başkasına zarar veremez. İyi derleyicilerin hemen hepsi, sözdizimi hatalarını derleme anında (compile time) bildirirler. Böylece sözdizimi hatasının giderilmesi (debug) kolaylaşır. Koşma Hataları (RunTime Error) : Bazı programlarda, derleyici sözdizimi hatası görmez ve programı derler. Ancak, program koşarken, çok farklı nedenlerle koşma eylemi durabilir. Örneğin, programın koşması için gerekli olan bir çevre biriminin olmayışı (yazıcı, bir kayıt ortamından dosya okuma, başka bir kayıt ortamına veri gönderme vb) koşmayı durdurur. Eğer program kullanıcıya doğru uyarılar gönderiyorsa, bu tür hatalar sorun yaratmadan kullanıcı tarafından giderilir. Bazı koşma hataları programın özüyle ilgili olabilir. Sözdizimi doğrudur; ama koşma anında gerçekleşmesi mümkün olmayan bir işlem istenmiş olabilir. Örneğin, bir işlemde sıfıra bölme oluşuyorsa, bu hatayı derleyici farketmez; işleminin yapılamadığı, ancak koşma anında ortaya çıkar. Programın özüne ilişkin koşma hataları, mantıksal hatalar kadar tehlikeli olmamakla birlikte, programın kaliteli olmadığının göstergesidir. Mantıksal Hatalar (Logical Errors) : Sözdizimi (syntax) hatası içermeyen program derlenir ve koşar. Ancak, işlemlerde mantıksal hata olabilir. Örneğin, bir bankada faiz hesaplayan formül yanlış yazılmış olsun. Yazılan formüle göre daha az ya da daha çok faiz hesaplanacaktır. Böyle bir hatayı derleyicinin görmesi olanaksızdır. Bu tür hatalar, ancak dikkatli kullanıcılar tarafından farkedilebilir. Farkedilmeden programın çalışması, ileride giderilmesi çok zor sorunlar yaratır. O nedenle, mantıksal hatalar, en tehlikeli hatalardır.
© Copyright 2024 Paperzz