Pages

C# ve Nesne Yönelimli Programlamanın 3 Prensibi

Kapsülleme (Encapsulation)
Nesne yönelimli programlamanın ilk prensibi kapsülleme (encapsulation) olarak adlandırılır. Bu özellik, dilin nesne kullanıcısından gereksiz uygulama ayrıntılarını saklayabilme yeteneği olarak ifade edilebilir. Örnek olarak .Net Framework temel sınıf kütüphanesi içerisinde yer alan ve Open() ve Close() metotlarına sahip SqlConnection sınıfını ele alalım.
  //SqlConnection, veritabanına yapılan bağlantının detaylarını kapsüllemektedir.
SqlConnection baglanti = new SqlConnection("server = London; database = AdventureWorks; integrated security = true");
baglanti.Open();
  //Burada veri yönetilir.
baglanti.Close();

SqlConnection sınıfı, veritabanına açılan bağlantının sağlanması, yüklenmesi, yönetimi, kapanması gibi içsel detayları gizlemiştir. Nesne kullanıcısı kapsüllemeyi sever; çünkü programlama görevlerini daha kolay hale getirir. SqlConnection sınıfında olduğu gibi, nesnenin görevini yerine getirmesi için arka tarafta çalışan onlarca satır kodu düşünmeye gerek yoktur. Tek yapılması gereken nesne örneğinin oluşturulması ve uygun metotların çağrılmasıdır.

Kapsüllemenin diğer bir işlevi ise veri korumadır. Bir sınıf tasarımında doğru olan, nesnelerin durum verilerini private erişim belirleyicisi ile koruma altına almaktır. Bu yolla dış dünya, alanın değerini elde etmek ya da değiştirmek istediğinde bir kontrolden geçmek zorunda kalır. Dış dünyaya açık, yani public erişim belirleyicisine sahip alanların sorunu, ait oldukları sınıfın iş mantıklarını algılayabilme yeteneklerinin olmamasıdır. Dolayısıyla atanan değerin iş mantığına (business logic) uygun olup olmadığına dair herhangi bir kontrolün sınıf içerisinde yapılabilmesi mümkün olmamaktadır. Nesne kullanıcısı genelde sınıfı yazan kişi olmakla birlikte harici birisi de olabilir; dolayısıyla böyle bir kontrolü nesne kullanıcısı tarafında yapmak akla gelse de ; bu çok efektif bir yol olmaz. Sınıfların durum verileri olarak anılan alanlar, private erişim belirleyicisi alarak dış dünyaya kapatıldıklarında başlangıç değerleri, sınıf içerisinde tanımlandığı yerde ya da yapıcı metot yardımıyla verilebilir. Böyle bir kapsülleme tercih edilebilir; ancak bazı durumlarda alanın değerinin dışardan okunması, değerinin sadece içsel olarak sınıf üyeleri tarafından atanması, durum verileri üzerinde yapılacak değişikliklerin dışarıya açılması gerekebilir. Burada değişiklikle birlikte gelen verinin kontrol edilerek istenmeyen durumların önüne geçilmesi gerekliliği ortadadır.
Kapsülleme, durum verilerinin tutarlılığını sağlamak için bir yol sunmaktadır: public eirşim belirleyicisine sahip alanlar tanımlamaktansa, alan verilerini private olarak tanımlamak alışkanlık haline getirilmelidir (Herhangi bir iş kuralı olmasa da). Bu durumda alanlar nesne kullanıcısına iki teknikle açılabilir:


- Nesne yönelimli diğer diller için geleneksel yol olan Erişen ve Değiştiren (Accessor and Mutator) metotlar tanımlamak.
- Bir özellik (property) tanımlamak.

Hangi teknik kullanılırsa kullanılsın iyi kapsüllenmiş bir sınıf, ham verisini (yani alanlarını) ve onu nasıl yönettiğinin ayrıntılarını dış dünyanın kem gözlerinden gizlemelidir. Bu yaklaşımın güzel ve faydalı olan yanı, sınıfı yazan kişinin, çalışan kodu bozmadan kapalı kapılar ardında metodun ya da özelliğin uygulanışını değiştirmekte serbest olmasıdır. .NET Framework temel sınıf kütüphanesi, geleneksel Erişen/Belirleyen metotlar yerine tip özelliklerini tercih eder. Bu yüzden sınıf kütüphanesi ile sağlıklı bir şekilde etkileşen programlar için kendi tiplerimizi yazarken özelliklerden faydalanmak doğru bir davranış olacaktır. Ayrıca özelliklerin bir alanın değerini işaret edip alana değer atamaları zorunlu değildir. Bir alan olmadan da özelliklerden faydalanılabilir.  
Kalıtım (Inheritance)
Kapsüllenmiş bir sınıf geliştirmeyi analiz ettikten sonra, şimdi sıra birbirleriyle ilişkili sınıf aileleri oluşturmaya geldi. Nesne yönelimli programlamanın ikinci prensibi olan kalıtım (inheritance), dilin varolan sınıf tanımlamalarının üzerine yeni bir sınıf tanımlaması inşa edilmesine izin verme yeteneği olarak ifade edilebilir. Kalıtım, bir türetilen sınıfın (base class ya da parent class) özellik ve davranışlarını, bir alt sınıfın miras alarak sanki kendi üyeleriymiş gibi kullanmasıdır.   

image
Yukarıdaki şekil, şöyle yorumlanabilir: Kare bir şekildir, şekil ise bir object’dir. Sınıflar arasında bu tarz bir ilişki oluşturulduğu zaman, tipler arasında bir bağlılık inşa edilmiş olur. Kalıtım fikrinin altında yatan en basit fikir, yeni sınıfın varolan bir sınıfın fonksiyonelliklerine sahip olması ve muhtemelen genişletmesidir. Kalıtım konusu ile ilgili belirtilmesi gereken bir ayrıntı vardır: .NET dünyasında her tip, eninde sonunda ortak bir temel sınıftan (base class) türer: System.Object. Object sınıfı, .NET ekosisteminde yer alan bütün tipler tarafından desteklenen üyeler kümesini tanımlamaktadır. Herhangi bir temel sınıf belirtmeden tanımlanan bir sınıf, bilinçsizce Object sınıfından türer. 
Kalıtıma başvurmak için şu iki sebepten birisi olmalı : (1) Var olan bir tipe yeni fonksiyonellikler eklenmek istendiğinde. (2)Birbiriyle ilişkili sınıfların birçok ortak üyesi bulunması durumunda . Kalıtımın uygulandığı yerde, bir temel sınıftan türeyen sınıflar, bütün temel sınıf üyelerini miras alırlar.
.NET Framework içerisinde örnek vermek gerekirse System.Windows.Forms.Control sınıfı, kendi yazacağımız bir windows kontrolünün ve System.Windows.Forms.Button, System.Windows.Forms.TextBox gibi var olan windows kontrollerinin temel sınıfı olarak kullanılmaktadır. 
Altı çizilmesi gereken bir diğer ayrıntı ise şudur: Kalıtım, kapsüllemeyi korur. Dolayısıyla türeyen sınıflar, temel sınıfın private erişim belirleyicisine sahip üyelerine erişemezler. 
Temel sınıflar (base classes) hakkında konuşmak gerekirse C#’da, bir sınıf direk olarak sadece tek bir temel sınıfa sahip olabilir. Dolayısıyla tek bir tipin, birden fazla temel sınıfının olması mümkün değildir. Buna karşın C#, bir sınıfın istenilen sayıda arayüzü (interface) uygulamasına izin vermektedir. Yani C#’da çoklu kalıtım (multiple inheritance) ancak arayüzler (interface) ile sağlanabilir.


Çok Biçimlilik (Polymorphism)
Nesne yönelimli programlamanın son prensibi, çok biçimlilik (polymorphism) olarak adlandırılır ve şu soruya cevap verir: Türeyen sınıflar, temel sınıfta yer alan bir üyeyi nasıl farklı şekillerde uygulayacaklardır? Çok biçimlilik, temel sınıfta yer alan bir üyenin (metot, özellik, indeksleyici ya da olay), türeyen sınıf tarafından nasıl değiştirileceğine dair bir yol sunmaktadır. Bu yoldan ilerlemek için öncelikle virtual ve override anahtar kelimelerinin çalışma mekanizmalarının anlaşılması gerekmektedir.
Bir temel sınıf, tanımlayacağı üyenin uygulanışının -yani içerisindeki kodların-, kendisinden türeyen sınıflar tarafından değiştirilebilmesini istiyorsa bu üye virtual anahtar kelimesi ile işaretlenmelidir. 
Türeyen bir sınıf, virtual anahtar kelimesi ile işaretlenmiş bir üyenin uygulanışını kendi sınıfına ait bir iş mantığıyla değiştirmek isteyebilir; ancak zorunda değildir. Üyenin başına override anahtar kelimesi yazılarak yeniden kodlanması ile böyle bir değişiklik mümkün olmaktadır. Ayrıca ezilen (overriden) her üye, ihtiyaç duyulması halinde temel sınıfta yer alan uygulanışı yeniden çağırmakta serbesttir: Kod içerisinde istenen herhangi bir yerde temel sınıfın bir üyesi base anahtar kelimesi ile çağrılabilir.

Hiç yorum yok: