|
C# 'ta Kapsülleme, Erişim Belirteçleri ve Polymorphism |
|
Gönderiliyor lütfen bekleyin... |
|
|
Geçen yazımda inheritance'
tan bahsederken encapsulation diye bir kavramdan bahsetmiştik, şimdi bu kavramı
açıklayacağım. Daha önceki yazımda
belirttiğim gibi 3 OOP prensibinden biri. Türkçe karşılığına gelirsek kapsülleme
demek. Ancak bilgisayar terimi olarak biraz açarsak kapsülleme, yönettiği kod
ve veriyi birbirine bağlayan ve bu ikisini dış kaynaklı karıştırma ve yanlış
kullanımdan koruyan bir mekanızmadır. Bu sayede veriyi dış ortamdan koruyan
bir ambalaj vazifesi gördüğünü de söyleyebiliriz. Şimdi kapsüllemeyi biliyoruz
da C#'ta yada .Net Framework'ünde ne gibi farklılıklar var diyeceksiniz? Öncelikle
.Net Framework'ünde gelen yeniliklerden bahsedelim.
I. Erişim belirteçlerinin(Access
Modifiers) varlığı kapsüllemeyi çok daha rahat yapabilmemize olanak sağlar.
Bu sayede bir metod veya bir değişken anahtar sözcükler(keywords) aracılığıyla
sadece önceden belirlenen sınırlar dahilinde kullanılabilir. Yada bunlara belirlenen
sınırlar içinden ulaşılabilir. Burada bahsedilen keyword'leri birazdan açıklayacağım.
(Tabii ki C#'ta kullanılan keywordleri açıklayacağım. Ve kullanımlarını basitçe
anlatacağım.)
II. Özellik(Property)
Sahalarının kullanımı (Bunun yapımını ilerde C# kodu ile göstereceğim.) Bu sayede
.Net Framework kapsüllemeyi destekler.
III. Soyut sınıf(abstract
class) ve soyut metodların(abstract methods) kullanımı. Aslında kalıtım(inheritance)
konusunu anlatırken taban sınıfımız(base class) soyut sınıf idi. Onun için bu
kısmı sadece açıklayacağım. Örnek vermeyeceğim. Örneği görmek isteyenler miras(inheritance)
konusunu anlattığım yazıdaki örneği incelerlerse istedikleri bilgiye ulaşabilirler.
Evet bu kadarlık
giriş yeter. Şimdi yukarıda anlattığım 3 maddeyi enine boyuna tartışalım.
I. Erişim belirteçlerinin
ne işe yaradıklarından yukarıda bahsettiğim için burada direkt erişim belirteçlerinin
neler olduklarını yazalım ve erişim sınırlarını çizelim. Erişim sınırları geniş
olandan dar olana doğru bir sıralama yaparsak.
- public: Bütün
her yerden erişilmek istenen veriler public anahtar sözcüğü ile birlikte kullanılır.
Sadece aynı proje içerisinden değil diğer projeler içerisinden de erişilebilir.
- internal: Aynı
assembly içindeki tüm sınıflar erişebilir. Yani public anahtar sözcüğünün
sadece aynı proje içinden erişilebileni. (VB .Net'te ise Friend anahtar sözcüğüne
karşılık gelir.)
- protected: Protected
anahtar sözcüğü ile birlikte kullanılan verilere ise sadece bir alt sınıfa
kadar erişilebilir.
- private: Bu
ise sadece tanımlandığı sınıfta geçerli olan veriler için kullanılır.
Ancak kontrollerde(controller)
yaygın olan kullanım şekli kontrollerin dışarıdan erişilmesi istenen metodlarının(aynı
anda diyelim ki 3 tane kontrol'ün belli metodlarının çalışması gerekli olabilir.)
public anahtar sözcüğü kullanılan bir metod içinde tanımlanmasıdır. Şimdi bu
durumun nasıl yapıldığını gösteren mini bir örnek kod yazalım. Kodda belirtilen
kontrollerin daha önceden tanımlanmış olduğunu düşünelim.
public void ChangeColor(Color
color)
{
this.groupBoxLine.BackColor = color;
this.groupBoxOutCity.BackColor = color;
this.groupBoxExternalPriceDetails.BackColor = color;
this.groupBoxInternalPriceDetails.BackColor = color;
this.groupBoxUser.BackColor = color;
this.groupBox1.BackColor = color;
this.btnAddNewLine.BackColor = color;
this.btnAddNewUser.BackColor = color;
this.btnCentralReport.BackColor = color;
this.btnChangePassword.BackColor = color;
this.btnDeleteExternalLine.BackColor = color;
this.btnDeleteInternalLine.BackColor = color;
this.btnDeleteUser.BackColor = color;
this.btnExit.BackColor = color;
} |
Yukarıdaki metod
bir renk parametresi gönderilerek çağrıldığı zaman yukarıda yazan bütün (daha
öncede private anahtar sözcüğü ile tanımlanmış olduklarını kabul etmiştik.)
kontrollerin rengini gönderilen renge değiştirmeye yarıyor. Bu sayede yukarıdaki
kontrollerin hepsinin BackColor dışındaki metodları dış dünyadan soyutlanmış
oluyor.
Aslında yaptığımız
metod public anahtar sözcüğü ile tanımlanmayıp internal anahtar sözcüğü ile
de tanımlanabilir. Bu bizim metodun içindeki kontrollere ait BackColor metodlarının
dış dünyadan ne kadar soyutlanmasını istediğimiza bağlıdır.
II. Özellik sahaları
sınıflara ait özel(private) değişkenlerin aynı metodlar gibi dış dünyaya açılmalarını
sağlıyor. Sadece okuma amaçlı dışa açılım yapılabildiği gibi hem okuma-hem yazma
amaçlı bir açılım da yapılabilir. Teorik olarak sadece yazma amaçlı da bir açılım
olsa da ne kadar mantıklı olur bilmem!!!! Şimdi örneklerimize geçelim.
private int currentExNumber
= -1;
private int loginStatus = 0;
public int CurrentExNumber
//Sadece okuma amaçlı özellik
{
get
{
return currentExNumber;
}
}
public int LoginStatus //Hem
okuma hem yazma amaçlı özellik
{
get
{
return loginStatus;
}
set
{
loginStatus = value;
}
}
|
Şimdi yukarıdaki
özellikleri kullanırken nesneadi.LoginStatus ve nesneadi.CurrentExNumber şeklinde
kullanabiliriz. Yalnız dikkat etmemiz gereken CurrentExNumber kullanılacağı
zaman sadece eşit işaretinin(=) sol tarafında kullanılabilecek olması. Çünkü
başta da belirttiğimiz gibi sadece okuma yapabildiğimiz için get metodu var.
Zaten bir değer atamaya kalkarsak hata verecektir.(Derleme esnasında özelliğin
sadece okuma amaçlı olduğuna dair debug penceresinden mesaj verir.) Bu sayede
de değiştirilmesini istemediğimiz ama kullanmak zorunda olduğumuz verilerin
dış ortamdan hem soyutlanmasına hem de bunların dış ortama belirli izinler dahilinde
açılımına izin vermiş olduk.
III. Aslında soyut
sınıf ve soyut metod'dan daha önce az da olsa miras konusunu anlatırken bahsetmiştim.
Ancak şimdi biraz polymorphism'den bahsederek bu kavramları biraz daha açacağım.
Polymorphism kapsülleme ve miras'dan ayrı düşünülemez. Polymorphism Yunancada
"çok formluluk" anlamına gelmektedir. Polymorphism ile soyut sınıf
arasındaki ilşkiden bahsetmeden önce soyut sınıf ve soyut metodlarla ilgili
bir iki ayrıntı daha verelim. Soyut sınıf sadece taban sınıflarında kullanılır
ve yeni nesne yaratılmasında kesinlikle kullanılamaz. (Yani new anahtar sözcüğü
kullanılamaz.)
Soyut metodlara
gelince bunların ise soyut sınıflarda kullanılacağından bahsetmiştik. Bunun
bize sağladığı avantaj bu metodların türetilen sınıflarda nasıl gerçekleştirildiğini
bilmek zorunda olmamamızdır. Aslında bunu söyleyerek polymorphism'in yararından
bahsetmiş olduk. Yani polymorphism veri soyutlaması yaparak sadece ilgilenmemiz
gereken olaylar ve verilerle ilgilenmemize olanak sağlıyor. Bu sayede taban
sınıfından türetilen ve aynı metodu farklı gerçekleştirimlerle(implementation)
kullanan birden fazla sınıfa sahip olabiliyoruz. En basit örnek üçgen bir çokgen,
kare de bir çokgen ve her ikisinin de bir alanı mevcut. Hemen basitçe bir taslak
çıkarırsak çokgen sınıfı soyut taban sınıfı ve alan adında soyut bir metoda
sahip. Üçgen ve kare sınıfları ise türetilen sınıflar ve alan metodunu istedikleri
biçimde gerçekleştiriyorlar. (Bu işlemlerin nasıl yapıldığı miras konusunu anlattığım
yazıda mevcuttur.)
Bir de soyut özellikler(abstract
property) var. Bunların kullanımı ise soyut metodlar ile özelliklerin birlikte
kullanımı ile ortaya çıkmakta. Buna bir örnek kod verirsem anlaşılması daha
kolay olacaktır. Ancak bunların kullanımına çok sık rastlamadığımı belirtmem
gerekir.
Sanırım aşağıdaki
örnek kod parçası soyut özelliklerin kullanımını daha da netleştirmiştir.
abstract class
Taban // Soyut sınıf
{
protected
int CurrentExNumber = -1;
public
abstract int GetCurrentExNumber// Soyut özellik
{
get;
}
}
class Turet: Taban
//Turet adlı bir sınıf türetiliyor
{
public
override int GetCurrentExNumber// overriding property
{
get
{
return
CurrentExNumber+1;
}
}
}
|
Polymorphism'den
bahsettik. Şimdi ise yalancı polymorphism'den bahsedelim. Aslında bir örnekle
biraz daha açarsam daha net olur. Diyelim ki bir karşılaştırma metodunuz var
ve hem integer hem de string veri tiplerini karşılaştırmak istiyorsunuz. Yalancı
polymorphism sayesinde aynı isimde iki metod yazarak bu isteğinizi gerçekleştirebilirsiniz.
Bunun için mini bir örnek kod yazalım isterseniz.
Aşağıda yazacağım
metodların aynı sınıf içinde yazıldığını düşünelim. Şimdi bu metodları kullanırken
metodların içinde yer aldığı sınıftan üretilen nesneninadi.karsilastir( yazdığımız
anda kod tamamlayıcısı bize iki seçenek sunar biri bu metodun iki tane integer
veri tipi ile çalıştığı, ikincisi ise bu metodun iki tane string veri tipi ile
çalıştığıdır. Bu sayede bir arabirim ile birden fazla metod gerçekleştirilmiş
olur.
Aslında bir metodun
birden fazla gerçekleştirime sahip olması olayına overloading denir.
Dikkat edilmesi
gereken nokta overloading ile overriding'in birbirine karıştırılmamasıdır. Unutmayın
overloading'te bütün işlemler aynı sınıf içerisinde oluyor. Overriding'te ise
tek bir sınıf yerine taban sınıfı ile bu sınıftan türetilen sınıflar işin içine
giriyor.
public void karsilastir(int
sayi1, int sayi2)
{
//Metodun iç implementasyonunu sizlere bıraktım.
}
public void karsilastir(string data1, string data2)
{
Metodun iç implementasyonunu sizlere bıraktım.
}
Evet bu yazıda
anlatacaklarım sona erdi. Kafanıza takılan kısımlar için mail adresimi tekrarlıyorum
[email protected]
Makale:
C# 'ta Kapsülleme, Erişim Belirteçleri ve Polymorphism C#, Visual C# ve .NET Aytaç Özay
|
|
|
-
-
Eklenen Son 10
-
Bu Konuda Geçmiş 10
Bu Konuda Yazılmış Yazılmış 10 Makale Yükleniyor
Son Eklenen 10 Makale Yükleniyor
Bu Konuda Yazılmış Geçmiş Makaleler Yükleniyor
|
|