Nesne Yönelimli Programlamaya Giriş - 2 Cem Ahmet MERCAN http://www.be.itu.edu.tr/~mercan/ 16/04/2009
Nesne Yönelimli Programlama Kavramlar Class (Sınıf): Nesneyi tanımlayan teorik yapıdır. Nesnenin yetenek ve davranışlarını tanımlar. Nesneler oluşturulurken kullanılır. Sadece bir tarif ya da plandan ibarettir. Kendisi çalıştırılamaz. Veri tutamaz.
Nesne Yönelimli Programlama Kavramlar Object (Nesne)/ Instance (Örnek): Sınıfla tanımlanan yapının işleyen, çalışan, veriyi saklayıp, fonksiyonları çağıran ürün 'üdür. Sadece sınıfında tanımlanan özellikleri gösterir. Tarife göre yapılan kek, plana göre yapılan ev gibidir.
Nesne Yönelimli Programlama Kavramlar Interface (Arayüz): Sınıfla tanımlanan yapının (nesnenin), dış dünya ile iletişimi için hazırlanmış yöntemler (methods) bütünü. Message (Mesaj): Sınıfla tanımlanan yapının (nesnenin), dış dünya ile iletişimi için hazırlanmış yöntemlerden (methods) bir tanesi.
Object-Oriented Programlama 1 2 3 4 5 6 7 8 9 10 Global Değişken G Yerel Değişken M Method 4 Komut int int double Protected: Public: Yerel Değişken Z Komut Method 3 char double Komut Değiş. Sonu int Method 1 Method 2 Method 3 Method 4 int
Nesne Yönelimli Programlama Kavramlar Abstraction: Genelleştirme, sadeleştirme Encapsulation: Gizleme, koruma, izin vermeme Inheritance: Miras alma, özelliklerini devralma Polymorphism: Çok biçimlilik, birden fazla çeşiti aynı anda desteklemek.
Nesne Yönelimli Programlama Constructor: Kavramlar Sınıftan nesne üretildiği anda otomatik olarak çalıştırılan fonksiyondur. Destructor: Nesne sonlandırılmadan önce otomatik olarak çalıştırılan fonksiyondur.
Programlamada İstenen Özellikler Minimum Karmaşıklık Bakım Kolaylığı Taşınabilirlik Genişleyebilirlik Yeterli ve Gerekli Miktarda Özellik İçermek Yeniden Kullanılabilirlik Yüksek Çağrılma / Düşük Çeşitte Çağırma Bölümler Arası Maksimum Ayrışma Katmanlı Yapıda olmak Standart (Tanıdık ve Anlaşılabilir) bir yapı
Abstract Data Type(ADT) Genel Veri Tipi Gerçek hayatta kullandığımız, özellikleri belirli, tipik bir bilgiyi programımızda, günlük hayattakine mümkün olduğunca benzer bir yapı halinde kullanabilmemize yarar. Veriyi gerçek hayattaki haline daha benzer tutarak, programı daha anlaşılır kılar. Nesne yönelimli programlama (OOP)'nın iyi çalıştığı bir alandır, sıkça kullanılır. İyi bir örnek oluşturur, anlaşılması da kolaydır.
Abstract Data Type(ADT) Örnek - Tarih Bir belgede tarih sorulur. Ayrı ayrı gün, ay, yıl sorulmaz. Tarih bilgisi, pek çok yerde karşımıza çıkar. Genel yapısı sabittir. Bellirli bir duruma özel değildir. Bu hali ile tarih bilgisini programlarımızda kullamamız için hazırlanacak bir yapı pek çok yerde değişiklik yapılmadan kullanılabilir.
Sorunlar: Abstract Data Type(ADT) Örnek - Tarih Tarih bilgisi günlük hayatta değişik şekillerde ifade edilebilir. Göreceli (17 Mayıs, Dün, Bugün) ya da Kesin (11/05/96, 12 Aralık 2006) bir şekilde ifade edilebilir. Değişik ifade şekileri olsa da, hepsi aynı bilgiyi tutar. Tutarlı şekilde tarih bilgisini sunar. Ayrıca matematik işleri için kendine has bir yapısı vardır: 23/05/98+10gün=03/06/98
Abstract Data Type(ADT) Örnek - Tarih Girilen ya da hesaplanan her değerin tarih açısından doğruluğu sınanmalı ki, çok zor bir iş. Hesaplamalar çok karmaşık olacaktır. (30 gün sonrası hangi tarih?) Görüntülenirken değişik gösterimler gerekecektir.
Abstract Data Type(ADT) Örnek - Tarih Çözüm Seçeneklerimiz: Bir C programında gün, ay ve yıl bilgileri tutmak istersek seçeneklerimiz: 1.Karakter dizisi olarak tutmak 2.Ayrı ayrı (Ya da bir struct içinde) 3 integer olarak saklamak 3.Belli bir tarihten itibaren geçen süreyi, gün ya da saat gibi bir alt türe çevirerek tutmak.
Abstract Data Type(ADT) Genel Veri Tipi Bu dersin ilk bölümünde gördüğümüz Tarih, Kimlik, matrix ve vector sınıfları birer ADT'dir. Tarih örneğinde nesne yönelimli programlama çözümü olarak ADT yapısını kullanırsak: Veri koruma altındadır, gelişi güzel erişilemez. Bir arayüz (interface) aracılığı ile yukarıdaki saydığımız şartlara uyulmasını zorlayabiliriz.
Class Tarih class Tarih { ENCAPSULATION private: int Gun; int Ay; int Yil; Veri (Koruma altında) public: int gun() { return Gun;} int ay() { return Ay;} int yil() { return Yil;} bool ayarla(int g, int a, int y); Arayüz (Veriyi Kullanmak için) };
Class Tarih class Tarih { private: int Gun; int Ay; int Yil; public: int gun() { return Gun;} int ay() { return Ay;} int yil() { return Yil;} bool Tarih::ayarla(int g, int a, int y) { if ((g>0)&&(g<=31)) return false; if ((a>0)&&(a<=12)) return false; if ((y>0)&&(g<=9999)) return false; Gun=g; Ay=a; Yil=y; return true; } }; bool ayarla(int g, int a, int y); ABSTRACTION
Class Tarih Tarih bayram; Tarih tatiller[20]; Tarih * birgun; tatiller[0].ayarla(1,1,2010); x=tatiller[5].gun(); birgun->ayarla(1,11,1111); birgun=&bayram; // ENGELLENEN İFADELER bayram.gun=23; bayram.ayarla(23,4,2009); cout<< Gün: <<bayram.gun(); bayram.ay=4; bayram.yil=2009; cout<< Ay: <<bayram.ay(); cout<< Yıl: <<bayram.yil(); birgun->ayarla(12,26,2009); birgun->ayarla(-1,0,-19);
Abstract Data Type(ADT) Detayların saklanması Faydaları Değişiklikler, programda değişiklik gerektirmez Arayüz daha anlaşılır olur. Optimizasyon merkezi olacağından daha kolay Program belirgin bir şekilde daha doğru olur. Daha okunaklı ve kendi kendini açıklayıcı kod. Veriler programın içine dağıtılmaz. Ayrıntılı teknikler yerine, gerçek hayattakine benzeryen yapılarla çalışmanın rahatlığı
Class Fatura class Fatura { private: Tarih Kesim_tarihi; HAS-A RELATIONSHIP string Firma_adi; int Tutar; public: int fatura_gun() { return Kesim_tarihi.gun();} int fatura_ay() { return Kesim_tarihi.ay();} int fatura_yil() { return Kesim_tarihi.yil();} bool gir(int g, int a, int y, string firma, int tutar); };
Class Fatura2 - Inheritance class Fatura2 : public Tarih { private: string Firma_adi; IS-A RELATIONSHIP int Tutar; public: bool gir(int g, int a, int y, string firma, int tutar); };
Class Fatura2 - Inheritance class Fatura2 : public Tarih { private: }; public: string Firma_adi; int Tutar; bool gir(int g, int a, int y, string firma, int tutar); PUBLIC class Tarih { private: int Gun; int Ay; int Yil; public: int gun() { return Gun;} int ay() { return Ay;} int yil() { return Yil;} bool ayarla(int g, int a, int y); };
Class Fatura / Fatura2 // HAS-A RELATIONSHIP Fatura kanepe; GUN=kanepe.fatura_gun() // IS-A RELATIONSHIP Fatura2 kanepe; GUN=kanepe.gun() kanepe.gir(23,4,2009); kanepe.gir(23,4,2009); kanepe.ayarla(2,3,2000);
Class Fatura3 - Inheritance class Fatura3 : private Tarih { private: string Firma_adi; IS-A RELATIONSHIP int Tutar; public: int fatura_gun() { return gun();} int fatura_ay() { return ay();} int fatura_yil() { return yil();} bool gir(int g, int a, int y, string firma, int tutar); };
Class Fatura3 - Inheritance class Fatura3 : private Tarih { private: }; public: string Firma_adi; int Tutar; bool gir(int g, int a, int y, string firma, int tutar); PRIVATE class Tarih { private: int Gun; int Ay; int Yil; public: int gun() { return Gun;} int ay() { return Ay;} int yil() { return Yil;} bool ayarla(int g, int a, int y); };
Abstract Data Type(ADT) Constructor Nesne oluşturulurken otomatik olarak çalıştırılır. C++'da sınıfın adını taşıyan ve geri dönüş değeri olmayan fonksiyonlar constructor'dur. Örneğin: Tarih::Tarih(void){ Gun=1; Ay=1; Yil=1; } // Programda kullanımı Tarih a; cout<<a.gun(); //ekrana 1 yazar
Abstract Data Type(ADT) Constructor Parametre alabilir. Parametreli tanımlandı ise: Tarih::Tarih(int gun, int ay, int yil){ ayarla(gun,ay,yil); } // Programda kullanımı Tarih a(23,5,2009); cout<<a.gun(); //ekrana 23 yazar Aynı isimde birden fazla fonksiyona (parametreleri farklı olmalı, mesala 2 constructor) fonksiyon aşırı yüklemesi (overloading) denir.
Abstract Data Type(ADT) Overloading Parametreleri farklı ama aynı isimde birden fazla fonksiyon tanımlanmasıdır. Parametrelerin farklılığında, parametre isimleri Ya da fonksiyonun geri dönüş değeri dikkate alınmaz, sadece çağırılan parametrelerin tiplerine bakılır. Bu tipler farklı olmalıdır. Class'da ya da ayrık fonksiyonlar için mümkündür. Mesala 2 constructor tanımlanabilir.
Class Fatura2 - Overloading class Fatura2 : public Tarih { private: string Firma_adi; int Tutar; public: Tarih(void); Tarih(int gun, int ay, int yil); OVERLOADING bool gir(int g, int a, int y, string firma, int tutar); };
Abstract Data Type(ADT) Polymorphism Miras alınan sınıfta zaten tanımlı olan bir fonksiyon, miras alan sınıfta da (Parametreleri, ismi ve geri dönüş değeri aynı olarak) tekrar tanımlanabilir. Bu durumda miras ağacı boyunca aynı fonksiyon farklı işler yapabilir: // Uygun her tarih kabul Tarih a; a.ayarla(2,5,2003); // Firmadan eski tarihleri kabul etme Fatura2 b; b.ayarla(4,5,2005);
Class Fatura2 - Polymorphism class Fatura2 : public Tarih { private: string Firma_adi; public: int Tutar; POLYMORPHISM // Tarih ile ayni isimde ayarla fonksiyonu, ayni tipte parametreler bool ayarla(int gun, int ay, int yil); bool gir(int g, int a, int y, string firma, int tutar); };
Abstract Data Type(ADT) Destructor Nesne sonlandırılırken otomatik olarak çalıştırılır. C++'da sınıfın adının başında ~ taşıyan ve geri dönüş değeri ve parametresi olmayan fonksiyon destructor'dur. Ayrılan hafızaların serbest bırakılması Ya da dosya kapatılması gibi işler için kullanılır. Örneğin: Tarih::~Tarih(void){ free(hafiza); }
Referanslar (1) Code Complete, second edition, Steve McConnell, Microsoft Press, ISBN:0-7356-1967-0 (2) Introduction to Object-Oriented Programming Using C++, Peter Müller, http://gd.tuwien.ac.at/languages/c/c++oop-pmueller/tutorial.html