C# Sınıf (Class) Kavramı
Günlük hayatta kullanılan pek çok kelime bir sınıflandırmanın sonucu ortaya çıkmıştır. Örneğin insan, ev, araba vb. kelimeler bir tek nesneyi değil, ortak davranış ve özellikleri olan nesnelerin tümünü ifade etmek için kullanılır. Araba kelimesi ile tekerlekleri olan motorlu veya motorsuz her türlü kara taşıtından bahseder Bütün arabaların ortak davranışları (hızlandırılabilir, durdurulabilir, yönlendirilebilir vb.) ve ortak özellikleri (tekerlekleri, direksiyonları vb.) vardır. Bu ortak davranışlara ve ortak özelliklere sahip bütün nesneler için araba kelimesi kullanılabilir. İşte her an belki farkında olmadan yapılan bu sınıflandırma, nesne tabanlı programlama yaklaşımının temelinde de vardır.
C#’ta metotlar ve özellikler mutlaka bir sınıfın içinde olmalıdır. Metotlar bir veya daha fazla komutun bir araya getirilmiş halidir; parametre alabilirler, geriye değer döndürebilirler. Özellikler ise bellek gözeneklerinin programlamadaki karşılıklarıdır. Bu bakımdan özellikler değişkenlere benzerler. Aradaki en temel fark değişkenlerin bir metot içinde tanımlanıp yalnızca tanımlandığı metot içinde etkinlik gösterebilmesine rağmen özelliklerin tıpkı metotlar gibi bir üye eleman olmasıdır. Bu bakımdan özelliklerin tuttuğu değerlere daha fazla yerden erişilebilir.
Sınıf(Class) Mantığı
Nesne tabanlı programlamada gereken nesneleri sınıflar yardımıyla oluşturmaktır.Sınıfları, nesneleri oluşturmak için önceden oluşturulmuş bir kalıp veya ilk örnek (prototip) olarak da düşünülebilir. Örneğin, kâğıt üzerine detayları çizilmiş bir ev planını kullanarak aynı evden pek çok örnek ev oluşturulabilir. İşte burada kâğıt üzerindeki bu plan sınıftır. Bu plana bakılarak yapılan ev ise sınıftan oluşturulan nesne örneğidir.
Bir sınıftan nesne oluşturma işlemine örnekleme (instantiating) denir. Aynı sınıftan istenilen sayıda nesne örnek oluşturulabilir. Oluşturulan tüm nesneler daha önce sınıfta belirlenen özelliklere ve davranışlara sahip olur.
Sınıfların hangi özelliklere sahip olacağını yani hangi bilgileri saklayacağını sınıflar
içerisinde tanımlanan alanlar (üye değişkenleri) yardımıyla belirlenebilir. Sınıfların hangi
davranışlara sahip olduğu ya da hangi işlevleri yerine getireceğini ise sınıf tanımı içerisinde
yazılan metotlar (yöntemler) ile belirlenir.
Bisiklet nesnesini yukarıdaki şekilde gösterildiği gibi modellendiğinde dış dünyanın onu nasıl kullanılacağı da belirlenir. Örneğin, oluşturulan bisiklet örneğinin 18 vitesi varsa vitesi değiştirmek için yazılan metodun 1’den küçük ve 18’ den büyük sayıları kabul etmemesi gerekir.
Kapsüllemenin Amacı
Giriş bölümünde bilgi gizlemenin nesne tabanlı programlamanın avantajlarından biri olduğu hatırlatılmıştı. Kapsülleme (encapsulation) sayesinde bir sınıfı kullanırken o sınıfın nasıl çalıştığını bilmek zorunda kalınmaz. Sınıfın bir örneğini oluşturur ve ihtiyaç duyulan metotlar çağrılır. Metotlar yerine getirmeleri gereken işlevleri gerçekleştirdikleri sürece,metotların nasıl çalıştığı ile ilgilenmez ve böylece karışıklıktan uzak durmuş olunur. Kapsülleme aynı zamanda sınıfların metotlarını, verilerini ve alanlarını diğer nesnelerden saklayarak ve bunlara erişimi sınırlandırarak sizi yanlış kullanımlardan korur. Bunun nasıl yapıldığı erişilebilirlik konusunda ayrıntılı olarak görülecektir.
Sınıf Tanımlama
class Bisiklet { int hiz = 0; //Burada int tipinde bir alan tanımlanıyor int vites = 1; //Burada int tipinde bir alan tanımlanıyor public void VitesDegistir(int yeniDeger) { vites = yeniDeger; } public void Hizlan(int artis) { hiz = hiz + artis; } public void FrenYap(int azalma) { hiz = hiz - azalma; } public void BilgileriYaz() { Console.WriteLine("Vites: {0}", vites); Console.WriteLine("Hız: {0}", hiz); } }
Görüldüğü gibi Bisiklet sınıfının hiz ve vites adında iki alanı, ayrıca VitesDegistir, Hizlan, FrenYap ve BilgileriYaz adında dört metodu bulunmaktadır. Alanların aslında sınıf içerisinde tanımlanan değişkenlerden başka bir şey olmadığına dikkat edilmelidir. Nesne Tabanlı Programlamaya Giriş modülünde değişkenlerin nasıl tanımlandığı ve Nesne Tabanlı Programlamada Metotlar modülünde metotların nasıl bildirildiği öğrenilmişti. Aslında Bisiklet sınıfının tanımında hemen hemen hiç yeni söz dizimi yoktur. Burada sadece daha önce kullanılan kavramlar class anahtar kelimesi ile belirtilen bir sınıf kapsamı içerisine aldık ve ilerleyen konularda öğrenilecek metotların erişilebilirlik seviyeleri için public anahtar sözcüğü kullanıldı.
Sınıfı Kullanma
Daha önce bir sınıftan nesne oluşturma işlemine örnekleme denildiği belirtilmişti. Bir
sınıf tanımlandığında aslında yeni bir değişken türü tanımlamış olunur. Daha önce
oluşturulan “Bisiklet” türünden aşağıdaki gibi bir değişken tanımlansın:
Bisiklet b;
Bunun daha önce tanımlanan değişkenlerden hiçbir farkı yoktur. Örneğin daha önce
tamsayı (int) türünde bir değişkeni şöyle tanımlanır:
int sayac;
Sınıf tanımlamalarında farklı olan durum, değişkene new (yeni) anahtar sözcüğü ile
geçerli bir başlangıç verisinin atanması gerektiğidir.
Bisiklet b; b = new Bisiklet();
Oysa tam sayı türünde tanımlanan değişken için böyle bir şeye gerek yoktu.
int sayac; sayac = 1;
Görüldüğü gibi new anahtar sözcüğü bir sınıfın yeni bir örneğini yani yeni bir nesneyi oluşturmak için kullanılmaktadır. Bisiklet sınıfından iki bisiklet nesnesi oluşturan ve bunların metotlarını kullanan aşağıdaki örnek dikkatlice incelenmelidir ve ekran çıktısı anlamaya çalışılmalıdır.
class Program { class Bisiklet { //Alan tanımlarının public ifadesi ile başlamadığına dikkat ediniz. int hiz = 0; //int tipinde bir alan tanımlanıyor int vites = 1; //int tipinde bir alan tanımlanıyor public void VitesDegistir(int yeniDeger) { vites = yeniDeger; } public void Hizlan(int artis) { hiz = hiz + artis; } public void FrenYap(int azalma) { hiz = hiz - azalma; } public void BilgileriYaz() { Console.Write("Vites: {0}", vites ); Console.WriteLine("Hız: {0}", hiz); } } static void Main(string[] args) { // İki farklı bisiklet nesnesi oluşturuluyor Bisiklet bisiklet1 = new Bisiklet(); Bisiklet bisiklet2 = new Bisiklet(); bisiklet1.Hizlan(10); bisiklet1.VitesDegistir(2); bisiklet1.BilgileriYaz(); bisiklet2.Hizlan(10); bisiklet2.VitesDegistir(2); bisiklet2.Hizlan(10); bisiklet2.VitesDegistir(3); bisiklet2.BilgileriYaz(); } }
Ekran çıktısı:
Vites: 2 Hız: 10
Vites: 3 Hız: 20
Erişilebilirlik
Bir sınıf içindeki üyelere dışarıdan erişim sağlamak veya sınırlandırmak için erişim türleri belirlenmiştir. Nesne tabanlı programlama da beş tane erişim türü bulunmaktadır.
- public
- private
- protected
- internal
- protected internal
public: Bu erişim türü ile tanımlanmış sınıf üyelerine her yerden erişim izni verilmiş olur.
private: Bu erişim türünde tanımlanmış üyelere sadece aynı sınıf içerisinde tanımlanmış diğer üyeler tarafından erişim izni verilmiş olur.
protected: Bu erişim türünde tanımlanmış üyelere tanımlandık sınıf ve bu sınıftan türetilmiş diğer sınıflardan erişim izni verilmiş olur.
İnternal: Bu erişim türünde tanımlanmış üyelere aynı assembly içinden erişim izni verilmiş olur.
protected internal: Bu erişim türü protected ve internal erişim türlerinin veya işlemiyle birleştirilmiş halidir.
class veya struct‘lar public ya da internal olabilir, varsayılan olarak internal erişim türüne sahiptir.
Erişim türü belirlenmediği sınıf üyeleri varsayılan olarak private olarak kabul edilir.Yukarıdaki bisiklet örneğini ele alınsın. Bir tane bisiklet adında sınıf tanımlanmıştır. Bu sınıfın içinde integer tipinde hız ve vites adında iki tane de değişken tanımlanmıştır. Dikkat edersen bu değişkenlere erişim türü atanmamıştır. Dolayısıyla program tarafından varsayılan olarak private olarak tanınacaklardır. Private olarak tanındıkları için sadece bisiklet sınıfı içinden erişim sağlanacaktır. Programın ana blokunda bisiklet sınıfından türetilen nesneler tarafından erişilemeyecektir.
bisiklet1.vites = 2; // Hata verir (vites için sınıf içerisinde bir erişim belirleyici kullanılmadığı için private kabul edilecektir)
Fakat bisiklet sınıfının içinde tanımlanmış Hizlan metodu public olarak tanımlandığı için her yerden erişim imkânı vardır. Dolayısıyla programın ana blokunda tanımlanmış nesneler tarafından da erişilebilecektir.
bisiklet1.Hizlan(10); // Hata vermeyecektir.z/pre>
Adlandırma Kuralları
Erişilebilirlik kuralları yazılan kod içerisinde daha kolay görebilmek için aşağıdaki adlandırma kurallar yardımcı olur:
- Public alan ve metot adları büyük harfle başlamalıdır. Örneğin, VitesDegistir metodu public olduğundan “V” ile yazılmıştır. Bu adlandırma kuralına ilk defa Pascal programlama dilinde kullanıldığı için PascalCase adı verilmektedir.
- Private tanımlayıcılar küçük harfle başlamalıdır. Mesela vites alanı private olduğu için “v” ile yazılmıştır.
Kurucular (Constructors)
Kurucu (Constructor – Konstraktır diye okunur.) bir sınıfın örneği oluşturulduğunda kendiliğinden çalışan özel bir metottur. Sınıf ile aynı ada sahip olmak zorundadır, parametreler alabilir ama geri değer döndürmez. Tüm sınıfların bir kurucusu olmak
zorundadır. Aşağıdaki örnek Bisiklet sınıfının varsayılan kurucusunda vites alanına 2 değerini atamaktadır:
class Bisiklet { public Bisiklet() { vites = 2; } }
Dikkat edilirse kurucunun tanımında void anahtar sözcüğü kullanılmamıştır. Bunun nedeni kurucuların void (boş) değer bile döndürmemesidir. Yukarıdaki örnek bize kurucuların neden gerekli olduğuna dair ipucu verir. Bisiklet sınıfının örnekleri oluşturulurken otomatik olarak çalışan bu metot her örnek için vites değerini 2 olarak belirleyecektir. Böylece oluşturulan her bisiklet yola 2. vites ile başlayacaktır. Görülen kurucular sınıf başlatılırken yapılması gereken işlemleri yapmak için mükemmel bir yerdir.
Varsayılan Kurucu
Programlama dilinde varsayılan (default) kurucu herhangi bir parametre almayan kurucudur. Bisiklet sınıfını tanımlarken bizim de yapılan bu kurucu yazılmasa bile derleyici, kişinin yerine hiçbir şey yapmayan bir varsayılan kurucu üretir.
Aşırı Yüklenmiş Kurucu
Tüm metotlar gibi kurucular da aşırı yüklenebilir. Tanımlanan sınıftan örneği oluşturulan bazı nesnelerin farklı durumlarda başlatılması gerektiğinde kurucular aşırı yüklenebilir. Bunu daha iyi açıklamak için Bisiklet sınıfını oluşturulacak her bisiklet örneği, farklı vites sayısı ile oluşturabilmeyi sağlayan metot aşağıdaki gibi değiştirildi.
class Bisiklet { int hiz = 0; int vites = 1; int vitesSayisi = 6; public Bisiklet() { vites = 2; } public Bisiklet(int deger) { vites = 2; vitesSayisi = deger; } }
Yukarıdaki kod incelenirse artık varsayılan kurucuyu kullanarak oluşturulan bisikletlerin 6 vitesli olduğu görülebilir. Eğer 21 vitesli bir bisiklet örneği oluşturmak istenirse kurucunun parametre alan sürümü kullanılarak bunu gerçekleştirmek gerekir. Kurucunun aldığı parametre değeri vitesSayisi alanının başlangıç değerinin üzerine yazacaktır. Çünkü kurucu, alanların ilk değerleri atandıktan sonra çalıştırılır.
Bisiklet cocukBisikleti = new Bisiklet(); // 6 vitesli bisiklet Bisiklet dagBisikleti = new Bisiklet(18); // 18 vitesli bisiklet
Nesnenin örneği oluşturulurken derleyici new ifadesinde kullanılan parametrelere
bakarak hangi kurucuyu çalıştırması gerektiğin belirler. Yukarıdaki örnekte dagBisikleti nesnesini oluştururken tam sayı türünde parametre girildiği için derleyici int parametre alan kurucuyu çalıştırır.
Kaynak: Megep Modülleri
Sonunda işin felsefesine ve uygulamasına aynı anda değinen bir türkçe kaynak bulabildim. Elinize sağlık, çok çok güzel bir anlatım, bayıldım.
çok iyi
Cok güzel ve aciklayici bir yazi olmuş emeği gecenlere sonsuz teşekkürler.