======== Nesnel Programlama (Object Oriented Programming) ========
Bunu da şu alt başlıklar altında inceleyebiliriz:
==== a) Encapsulation: C++ dilinde, veri yapıları ile bu verileri işleyen kodlar, "class" adı verilen bir soyutlama kavramı altında birbiri ile sıkı bir şekilde ilişkilendirilir. Böylece bu veri yapılarını hangi fonksiyon işleyecek? Acaba doğru fonksiyona mı verdik? gibi tereddütler ortadan kalkmış oluyor. Belli bir class'dan nesneler türetiyoruz ve bu nesnelerin hem kendilerine özgü verileri, hem de kendilerine özgü davranış biçimi elde ediyoruz. C dilinde böyle bir yapı yoktur. Veriler ayrıdır, Kodlar ayrıdır. Belli bir veri için doğru kodu kullanmak, programcının sorumluluğundadır.
==== b) Abstraction: C++ dilinin sağladığı "class" kavramı ile türetilen nesneler, yaptıkları işın detaylarını dış dünya'ya gizlerler, ve sadece o nesnenin etkili bir şekilde kullanması için gerekli arabirimi dışa açık hale getirirler. Bu, büyük çaplı, karmaşık programlarda çok büyük bir avantajdır. Detaylarda kaybolmadan, daha üst seviyede düşünüp ona göre tasarım yapmanın önünün açar.
==== c) İnheritance: C++ dilinde, "class" ile oluşturulan temel nesneler, daha karmaşık ve daha fazla işlevsellik sağlayan "üst nesnelerin" yapıtaşı olarak kullanılabilir. Örneğin bir grafik kütüphanesinin sağladığı alt seviye nesneleri düşünelim.
Kod:
class POINT
{
private:
int x;
int y;
};
class PIXEL: public POINT
{
private:
unsigned int color;
};
Şimdi burada ne yaptık? Temel yapıtaşı olarak POINT var elimizde ve iki boyutlu koordinat sistemindeki bir noktayı ifade ediyor. Bu yapıtaşını geliştirip PIXEL yapıtaşını oluşturuyoruz. PIXEL, POINT'un sağladığı bütün imkanları içeriyor, ama onlara renk değerini tanımlama olanağını ekliyor. Bu sistem, değişik amaçlar için aynı kodu tekrar tekrar yazıp gereksiz fazlalığın önüne geçmesi açışından çok büyük bir avantajdır.
==== d) Polymorphism: C++ dilinin en güçlü ve kullanışlı özelliklerinden birisi de polymorphism olayıdır. Burada, aynı temel yapıtaşından türetilmiş, ama ilave olarak farklı davranışlar gösteren nesneler tanımlanabilir. Aşağıdaki programı inceleyelim:
Kod:
#include <stdio.h>
class COMP_FILE
{
public:
virtual void uncompress() = 0;
};
class ZIP_FILE : public COMP_FILE
{
public:
void uncompress()
{
printf("uncompressing ZIP_FILE\n");
}
};
class RAR_FILE : public COMP_FILE
{
public:
void uncompress()
{
printf("uncompressing RAR_FILE\n");
}
};
class LZO_FILE : public COMP_FILE
{
public:
void uncompress()
{
printf("uncompressing LZO_FILE\n");
}
};
void uncompress_file(COMP_FILE& file)
{
file.uncompress();
}
int main()
{
ZIP_FILE zip;
RAR_FILE rar;
LZO_FILE lzo;
uncompress_file(zip);
uncompress_file(rar);
uncompress_file(lzo);
}
[ta@bonsai ~]$ ./uncompress
uncompressing ZIP_FILE
uncompressing RAR_FILE
uncompressing LZO_FILE
[ta@bonsai ~]$
Burada COMP_FILE diye, genel anlamda sıkıştırılmış bir dosyayı temsil eden class var. Bundan türetilmiş olan ZIP_FILE, RAR_FILE, LZO_FILE class'ları var. Eğer bu üç class'ı program içinde sadece COMP_FILE pointer olarak kullanırsak, kesinlikle tam olarak ZIP dosyası mı, RAR mı, LZO mu bilmemize gerek olmadan bu dosyaları açabiliriz. Bunun için uncompress_file fonksiyonuna COMP_FILE olarak nesneyi aktarıyoruz, o fonksiyon da, nesnenin uncompress alt fonksiyonunu çağırıyor. Ve nesnenin ne olduğuna bağlı olarak da, doğru bir şekilde dosya açılmış oluyor!
Bu kavram, birçok çeşit nesne ile çalışıyorsak, ve bu nesneler büyük ölçüde aynı davranışı gösteriyor, ama birkaç alanda birbirinden ayrılıyorsa, programımızı çok daha temiz ve basit haline getirecektir.