14 Nisan 2010 Çarşamba

Object Oriented Programming (16) - Constructors, Destructor

Constructors, Destructor


Yapıcı metodlar olarak adlandırılan Constructor'lar nesne yönelimli programlamada çok büyük öneme sahiptir. Constructor'lar(Yapıcı Metodlar), Class üzerinden oluşturulan her bir nesnenin(Object) ilk çalışacak void'leridir. Her nesne en az bir Constructor'a sahiptir. Bu constructor Default Constructor(Varsayılan Yapıcı Metod) olarak adlandırılır. Bunun dışında isteğe göre parametrik Constructor'lar oluşturulabilir.

Constructor'lar genellikle bir nesnenin field'larına başlangıç değerleri atamak için kullanılır.

Constructor'lar Class üzerinden nesne oluşturulduğu zaman Common Language Runtime (CLR) tarafından otomatik olarak çalıştırılır.

Constructor Tanımlamak

Constructor tanımlarken aşağıdaki adımlara dikkat edilmesi gerekir. Bunlar;

• Constructor isimleri Class ile aynı olmalıdır.
• Constructor'lar geriye değer döndürmez. Fakat Constructor'lar parametre değerleri alabilirler. Bu parametreleri belirlerken method overload kuralları(parametre sayı ve türlerinin farklı olması) geçerli olur. Default Constructor parametre değeri almaz.

Aşağıda Constuructor tanımlaması gösterilmektedir.

access-modifier class-adı(parametre-listesi)
{


}

Aşağıdaki örnekte _uzunluk adlı field'ın başlangıç/varsayılan değerini sekiz yapan, Default Constructor tanımı yapılmaktadır.

//Constructor
public Sifre()
{
  _uzunluk = 8;
}


//Field
private int _uzunluk;


//Property
public int Uzunluk
{
get { return _uzunluk; }
set { _uzunluk = value; }
}

Aşağıdaki örnekte _uzunluk adlı field'ın değerini Class üzerinden Nesne oluşturulurken alan , Parametrik Constructor tanımı yapılmaktadır.

//Constructor
public Sifre(int UzunlukDegeri)
{
    _uzunluk = UzunlukDegeri;
}


//Field
private int _uzunluk;


//Property
public int Uzunluk
{
get { return _uzunluk; }
set { _uzunluk = value; }
}

Aşağıdaki örnekte _uzunluk ve _sifreTipi adlı field'ların değerini Class üzerinden Nesne oluşturulurken alan , farklı bir Parametrik Constructor tanımı yapılmaktadır.

//Constructor
public Sifre(int UzunlukDegeri, SifreKarakterTipi SifreTipiDegeri)
{
_uzunluk = UzunlukDegeri;
_sifreTipi = SifreTipiDegeri;
}


//Field
private int _uzunluk;
private SifreKarakterTipi _sifreTipi;


//Property
public int Uzunluk
{
get { return _uzunluk; }
set { _uzunluk = value; }
}


public SifreKarakterTipi SifreTipi
{
get { return _sifreTipi; }
set { _sifreTipi = value; }
}

Constructor ekledikten sonra Sifre Class'ının son hali aşağıdaki gibidir.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace SifreUretici
{


//Enum
public enum SifreKarakterTipi
{
     Basit, Kompleks, Ozel
}


public class Sifre
{


//Constructor
public Sifre()
{
    _uzunluk = 8;
}


public Sifre(int UzunlukDegeri)
{
     _uzunluk = UzunlukDegeri;
}


public Sifre(int UzunlukDegeri, SifreKarakterTipi SifreTipiDegeri)
{
      _uzunluk = UzunlukDegeri;
      _sifreTipi = SifreTipiDegeri;
}

//Field
private int _uzunluk;
private SifreKarakterTipi _sifreTipi;

//Property
public int Uzunluk
{
get { return _uzunluk; }
set { _uzunluk = value; }
}


public SifreKarakterTipi SifreTipi
{
    get { return _sifreTipi; }
    set { _sifreTipi = value; }
}


//Method
public string SifreUret()
{
char[] karakter = { 'A','B','C','D','E','F','G','H','I', 'J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','1','2','3','4','5','6','7','8','9','0','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','!','@','?','$'};
Random rnd = new Random();
string sonuc = null;
for (int i = 1; i <= _uzunluk; i++)
{
int rastgeleSayi = 0;
if (_sifreTipi == SifreKarakterTipi.Basit)
{
rastgeleSayi = rnd.Next(0, 25);
}
else if (_sifreTipi == SifreKarakterTipi.Kompleks)
{
rastgeleSayi = rnd.Next(0, 61);
}
else if (_sifreTipi == SifreKarakterTipi.Ozel)
{
rastgeleSayi = rnd.Next(0, karakter.Length - 1);
}
sonuc += karakter[rastgeleSayi].ToString();
}
return sonuc;
}
} //Class
} //NameSpace

Constructor'lar ekledikten sonra Sifre Class'ının Class View'da ki görüntüsü aşağıdaki gibi olacaktır.

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Destructor(Yıkıcı Metod), Constructor'ın tersine nesne(object) yok edilirken devreye giren void'lerdir. Genelde bellek temizleme işlemlerinde yardımcı olmak amacıyla kullanılır. Aslında Visual Studio .NET de bellek yönetiminden Garbage Collector(GC) sorumludur. Destructor sadece Garbage Collector'ın manuel bir şekilde kullanılmasını sağlar. İşlem bittikten sonra Garbage Collector tarafından ilgili nesne bellekten kaldırılır.

Çöp toplama aracı olarak da bilinen Garbage Collector(GC), bellek yönetiminden sorumlu araçtır. GC servisi, bellek üzerinde allocate(yeni nesnelere yer açma) ve deallocate(bellekte uygun alanları serbest bırakma) işlemlerini gerçekleştirir. Ayrıca uzun süre erişilmeyen veya kullanılmayan nesneleri bellekten kaldırma, oluşturulan yeni nesneler için heap üzerinde yer açma gibi işlemleri de yerine getirir.

Daha önceki Microsoft uygulamalarında(Visual Basic), nesneyi bellekten temizlemek için nesneye Nothing değeri atıyorduk.

x = Nothing

Fakat bu işlem; nesneye Nothing değerini atamayı unutmamız, bağlı nesneleri yönetimi zorlaştırma gibi problemlere yol açmaktaydı. GC bu tür problemlerin hepsini ortadan kaldırarak bellek yönetimini otomatik hale getirir.

Bellek yönetimini daha etkin hale getirebilmek için GC'yi manuel olarak kontrol etmek gerekebilir. GC'nin manuel kontrol edilmesi Interface bölümünde daha detaylı ele alınacaktır.

Destructor Tanımlamak

Destructor tanımlarken aşağıdaki adımlara dikkat edilmesi gerekir. Bunlar;

• Destructor isimleri "~"(tilde) karakteri ve Class adının birleşimiyle oluşur. Ör ~Sifre().
• Destructor'lar parametre almaz ve geriye değer döndürmez.
• Bir Class içerisinde sadece bir Destructor tanımı yapılabilir.

Aşağıda Destructor tanımlaması gösterilmektedir.

~class-adı()
{


}

Aşağıdaki örnekte Sifre Clası için Destructor tanımı yapılmaktadır.

~Sifre()
{
// Finalize gerçekleşmeden önce yapılması
// gereken işlemler burada gerçekleştirilir
}

Destructor ve GC'nin manuel kullanımı Interface bölümünde detaylı bir şekilde ele alınacaktır.

Object Oriented Programming (15) - Class'ın Son Hali

Sifre Class'ının son hali aşağıdaki gibidir.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SifreUretici
{

//Enum
public enum SifreKarakterTipi
{
Basit, Kompleks, Ozel
}


public class Sifre
{


//Field
private int _uzunluk;
private SifreKarakterTipi _sifreTipi;


//Property
public int Uzunluk
{
get { return _uzunluk; }
set { _uzunluk = value; }
}


public SifreKarakterTipi SifreTipi
{
get { return _sifreTipi; }
set { _sifreTipi = value; }
}


//Method
public string SifreUret()
{
char[] karakter = { 'A','B','C','D','E','F','G','H','I', 'J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','1','2','3','4','5','6','7','8','9','0','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','!','@','?','$'};
Random rnd = new Random();
string sonuc = null;
for (int i = 1; i <= _uzunluk; i++)
{
int rastgeleSayi = 0;
if (_sifreTipi == SifreKarakterTipi.Basit)
{
rastgeleSayi = rnd.Next(0, 25);
}
else if (_sifreTipi == SifreKarakterTipi.Kompleks)
{
rastgeleSayi = rnd.Next(0, 61);
}
else if (_sifreTipi == SifreKarakterTipi.Ozel)
{
rastgeleSayi = rnd.Next(0, karakter.Length - 1);
}
sonuc += karakter[rastgeleSayi].ToString();
}
return sonuc;
}


} //Class
} //NameSpace

9 Nisan 2010 Cuma

Object Oriented Programming (14) - Class içerisine Enum türünden Field ve Property Eklemek

Class içerisine Enum türünden Field ve Property Eklemek


Enum, sabit elemanlardan oluşan ve bazı özel sözcükleri tam sayı olarak temsil etmemizi sağlayan özel bir tiptir.

Tanımı aşağıdaki gibidir
enum EnumAdi : tur{SOZCUK1,SOZCUK2,....,SOZCUKN}

Enum sabitlerinin türü byte, sbyte, short, ushort, int, uint, long ve ulong türlerinden herhangi biri olabilir. Eğer enum'un tür adı belirtilmediyse ,.NET IDE'si tarafından, varsayılan olarak int kabul edilir.

Enum tanımı Namespace içerisinde yapılır.

Aşağıdaki örnekte, Basit, Kompleks, Ozel sözcüklerinden olusan int tipinde bir enum tanımı yapılmıştır.

enum KarakterTipi
{
Basit,Kompleks,Ozel
}

KarakterTipi enum'u içerisindeki her sözcük bir rakamsal değer ile temsil edilir. Rakamsal bir değer atanmadığı sürece, Basit 0 ,Kompleks 1 , Ozel ise 2 değeri ile temsil edilir.

Eğer sözcüklerin temsil edildiği değerleri değiştirmek isterseniz aşağıdaki gibi bir işlem yapmanız gerekmektedir. Örnekte Basit 0 ,Kompleks 5 , Ozel ise 10 değeri ile temsil edilir.

enum KarakterTipi2 :int
{
Basit=0,Kompleks=5,Ozel=10
}

Aşağıdaki Örnekte, SifreUretici namespace'i altında, SifreKarakterTipi adında; Basit,Ozel ve Kompleks sözcüklerinden oluşan bir enum tanımladık.

namespace SifreUretici
{
//Enum
enum KarakterTipi
{
Basit, Kompleks, Ozel
}
public class Sifre
{

} //Class
} //NameSpace

Enum'u tanımladıktan sonra artık Enum türünden bir property yazabiliriz. Önce field'ı tanımlayarak başlıyalım. Örnekte _sifreTipi adında bir field tanımladık. Bu field, SifreKarakterTipi türünde tanımlanmıştır.

private SifreKarakterTipi _sifreTipi;

Şimdi _sifreTipi field'ı içerisindeki değeri okuyabilen ve değiştirebilen bir Property yazabiliriz. Propery oluşturmak için field satırının tamamını seçerek, art arda CTRL + R ve CTRL + E tuş kombinasyonlarına basarız. Açılan Encapsulate Field penceresinde OK butonu tıklayarak, SifreTipi adındaki property'i oluştururuz.

Sifre Class'ımızın görüntüsü aşağıdaki gibi olacaktır.

//Field
private SifreKarakterTipi _sifreTipi;


//Property
public SifreKarakterTipi SifreTipi
{
get { return _sifreTipi; }
set { _sifreTipi = value; }
}

SifreTipi Property'sinden seçilen değere göre şifre üretmek için, SifreUret metodunda aşağıdaki değişiklikler yapılır.

public string SifreUret()
{
char[] karakter = { 'A','B','C','D','E','F','G','H','I', 'J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','1','2','3','4','5','6','7','8','9','0','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','!','@','?','$'};
Random rnd = new Random();
string sonuc = null;
for (int i = 1; i <= _uzunluk; i++)
{
int rastgeleSayi = 0;
if (_sifreTipi == SifreKarakterTipi.Basit)
{
rastgeleSayi = rnd.Next(0, 25);
}
else if (_sifreTipi == SifreKarakterTipi.Kompleks)
{
rastgeleSayi = rnd.Next(0, 61);

}
else if (_sifreTipi == SifreKarakterTipi.Ozel)
{
rastgeleSayi = rnd.Next(0, karakter.Length - 1);
}


sonuc += karakter[rastgeleSayi].ToString();
}


return sonuc;
}

Object Oriented Programming (13) - Class İçerisine Method Eklemek

Class İçerisine Method Eklemek

Class içerisine method eklemek için, void yada function yazmak yeterli olacaktır.

Method'ların access modifier'ı public, private veya protected olabilir. Private modifier ile tanımlanan method'lar, sadece bulundukları Class içerisinde geçerli olurlar. Bu tür Method'lara iç method da denilebilir. Bu tür methodlar daha çok Class içerisinde tekrar eden işler için kullanılır.

Protected modifier ile tanımlanan methodlara, hem bulunduğu Class içerisinden hem de Inheritance (miras alındığı) yapılan Class içerisinden erişilebilir. Protected access modifier ile method tanımlama işlemi Inheritance (Miras Alma) konusunda detaylı bir şekilde ele alınacaktır.

Methodun Solution üzerinden erişilebilir olması için, method'u public access modifier ile tanımlanmanız gerekir. Access modifier eklenmeyen methodlar .NET IDE'si tarafından varsayılan olarak private modifier'lı kabul edilir.

Aşağıdaki örnekte, geriye 10 karakter uzunluğunda string değer döndüren, bir method tanımı yapılmıştır. Bu method ile karakterleri harf ve rakamdan oluşan rastgele şifreler üretilmektedir.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SifreUretici
{
public class Sifre
{
//Field
private int _uzunluk;


//Property
public int Uzunluk
{

get { return _uzunluk; }
set { _uzunluk = value; }
}

//Method


public string SifreUret()
{
char[] karakter = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' };


Random rnd = new Random();
int RastgeleSayi;
string sonuc = null;


for (int i = 1; i <= 10; i++)
{
RastgeleSayi = rnd.Next(0, karakter.Length - 1);
sonuc += karakter[RastgeleSayi].ToString();
}
return sonuc;
}


} //Class
} //NameSpace

Method içersisindeki işlemleri gerçekleştirirken field değerlerinden faydalanabiliriz. Örneğin yukardaki method da kullandığımız 10 karakterlik sabit şifre uzunluğunu, Uzunluk adında bir property'den alarak değişken hale getirebiliriz. Böylece SifreUret methodumuz, girilen şifre uzunluğuna göre otomatik olarak şifre üretir.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace SifreUretici
{


public class Sifre
{


//Field
private int _uzunluk;


//Property
public int Uzunluk
{
get { return _uzunluk; }
set { _uzunluk = value; }
}


//Method
public string SifreUret()
{
char[] karakter = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' };


Random rnd = new Random();
int RastgeleSayi;
string sonuc = null;


for (int i = 1; i <= _uzunluk; i++)
{
RastgeleSayi = rnd.Next(0, karakter.Length - 1);
sonuc += karakter[RastgeleSayi].ToString();
}
return sonuc;
}


} //Class
} //NameSpace

Son olarak Method isimleri belirlerken Fiil kullanmamız önerilir. Örnek: SifreUret(),Focus(),Clear() gibi...