Memik Yanık - Kişisel Web Sitesi Ana Sayfa | Hakkımda | Kitap Önerileri | Fotoğraflarım | RSS RSS | İletişim

12. BÖLÜM : CLASS'LAR ve NESNEYE YÖNELİK PROGRAMCILIK


C#, nesneye yönelik bir programlama dili olduğundan sürekli sınıflardan söz etmek, .NET Framework ile gelen sınıfları kullanmak gerekmektedir. Bundan sonra verilecek konuların kolay anlaşılmasını sağlamak için sınıfların temel özellikleri bu bölümde anlatılacaktır. 

A
şağıda verilen konsol uygulamasında 2 sınıf bulunmaktadır. Bu konsol uygulamasındaki 2. sınıfta herhangi bir metot yoktur. Bu uygulama hatasızca derlenir ama çalıştırıldığında herhangi bir işlem yapmaz.

 

Birden fazla sınıfta Main() metoduna yer verildiği zaman derleme sırasında /main parametresi ile hangi sınıftaki Main() metodunun kullanılmak istendiğini belirtmek gerektiğini konsol uygulamaları hakkında bilgi verilen bölümden hatırlıyor olmalısınız. Visual Studio ile hazırladığınız uygulamada birden fazla Class’ta Main() metodu varsa Project Properties penceresinde Startup Object liste kutusunda seçim yapmanız gerekir. 

Bu uygulamada Main() metodu ilk sınıf yerine 2. sınıfta olsaydı değişen bir şey olmazdı. Çünkü C# derleyicisi Main() metodunu bulup kodun oradan itibaren çalışmaya başlamasını sağlamaktadır. C# derleyicisi bir sınıfın içinde başka bir sınıfın olmasına izin vermektedir. 

Şimdi yukarıda verilen C# kodundaki 2. sınıfta bir metot hazırlayacağız. Bu metodu nesne hazırlamadan direk kullanabilmek için başına static anahtar kelimesini yazdık.



Gördüğünüz gibi bu şartlarda 2. sınıfta geriye herhangi bir değer göndermeyen(void) ve herhangi bir parametreye sahip olmayan “Mesaj” adında bir metot bulunmaktadır. Bu metodu diğer sınıflarda kullanabilmek için başına ayrıca public yazdık. 

Şimdi bu metodu ilk sınıfta kullanacağız. Bu metot başka bir sınıfın içinde olmasaydı metodu işletmek için metot adını yazmak yeterli olurdu. “Mesaj()” adı verilen bu static metot başka bir sınıfta yer aldığı için metot adından önce sınıfın adını yazdık. 

    class sinif_1 
     
       public static void Main() 
        
          sinif_2.Mesaj(); 
        
    } 

Bu şekilde düzenlenen konsol uygulaması derlenip çalıştırılırsa aşağıdaki gibi bir sonuç alınır. Bu sırada programın işletimi ReadLine() metodu ile askıya alınmış durumdadır. Enter tuşuna basılması halinde programın çalışması sona erer.



ReadLine() yerine ReadKey() metodunu kullanmış olsaydık enter yerine herhangi bir tuşa basabilirdik. Şimdi yukarıda verilen metodun başlangıç satırındaki static deyimini sileceğiz. 

    class sinif_2 
     
      public void Mesaj() 
        
         Console.Write("Devam etmek için bir tuşa basın"); 
         Console.ReadKey(); 
       
     

Bu şekilde düzenlenen konsol uygulaması derlendiğinde hata meydana gelir. Çünkü static olmayan metotlar “Sınıf adı.Metot adı” şeklinde çağrılıp işletilemezler. static olmayan metotları işletebilmek için önce o sınıftan yola çıkıp nesne hazırlamak gerekir. 

    class sinif_1 
     
       public static void Main() 
       
          sinif_2 Nesne; 
            Nesne = new sinif_2(); 
        
     } 

Bu kitapta şimdiye kadar birçok kez sınıflardan yararlanarak nasıl nesne hazırlandığını gördünüz. Yanda işaret edilen 2 satır ile “Sinif_2” tipinde bir değişken tanımlanmakta ve “Nesne” adı verilen nesne Sinif_2’den yola çıkılarak hazırlanmaktadır. 

Daha önceki konulardan bildiğiniz gibi bu 2 satırı veya 2 işlemi aşağıda yapıldığı gibi tek satırda yapmak mümkündür. Sınıftan yola çıkarak nesne hazırlandıktan sonra metodun önüne nesnenin adını yazarak işletebilirsiniz. 

    class sinif_1 
     
      public static void Main() 
      
        sinif_2 Nesne = new sinif_2(); 
          Nesne.Mesaj(); 
       
     
    class sinif_2 
     
      public void Mesaj() 
      
         Console.Write("Devam etmek için bir tuşa basın"); 
         Console.ReadKey(); 
      
     

Bu kodda sınıftan yola çıkarken new anahtar kelimesi ile nesne hazırlanırken Sinif_2() adında bir metot kullanılmaktadır. Bundan şu sonucu çıkarabilirsiniz. Hazırlanan her sınıf, kendisi ile aynı ada sahip ve nesne hazırlamaya yarayan bir metoda sahiptir. Sınıftan yola çıkılarak nesne hazırlanırken kullanılan bu metodu programcı hazırlamazsa C# derleyicisi otomatik olarak hazırlamaktadır. 

Sınıftan yola çıkılarak nesne hazırlanırken kullanılan ve sınıf ile aynı ada sahip(programcı hazırlamadıysa derleyici tarafından otomatik olarak hazırlanan metoda yapıcı(Constructors) adı verilmektedir. Başka bir deyişle Constructors adı verilen metot, sınıfın örneği new anahtar kelimesi ile hazırlarken kullanılan metottur. 

Şimdi “Sinif_2” adını vermiş olduğumuz bu class’a class ile aynı ad sahip ve işletilebilir herhangi bir satıra sahip olmayan bir metot ekleyeceğiz. Bu şartlarda üzerinde çalıştığımız konsol uygulamasındaki 2. sınıf 2 metoda sahip olmuş olacaktır. 

    class sinif_2 
     
      public void Mesaj() 
      
         Console.Write("Devam etmek için bir tuşa basın"); 
         Console.ReadLine(); 
      
      public sinif_2() 
      
      
    } 

Bu konsol uygulamasındaki 2. sınıftaki 2. metoda sınıfın adını vermiş olduğumuz için bu metot Constructors yani yapıcı metot görevini görür. B
u metot geriye bir değer göndermemesine rağmen void deyimini kullanmadık. Bu metot, sınıf ile aynı ada sahip olmasaydı bu şartlarda hata meydana gelirdi. Konunun devamında yapıcı, diğer adıyla Constructors metotlar hakkında bilgi verilecektir.

Sınıfların Alanlara Sahip Olması 

Yukarıda hazırladığımız sınıflarda yalnızca metotlar vardı. Sınıfların metotlardan başka ayrıca alanları olabilmektedir. Alanlar değer saklamak için tanımlanan değişkenler gibidir. Başka bir deyişle sınıf içinde tanımlanan değişkenlere alan adı verilmektedir. 

using System;
namespace Deneme

 class Ana_sinif 
 
  public static void Main() 
  
  
 

 
public class Cep_Fatura 
 
    public string Sahip; 
    public string Numara; 
    public string Adres; 
    public int Tutar; 
  }


Şimdi her ay adresime gelen cep telefonu ile ilgili faturayı temel alan basit bir sınıf hazırlayacağız. “Cep_Fatura” adı verilen sınıfın 4 alanı olacağı için bu sınıf içinde public özellikli 4 değişken tanımladık. 

Bu şekilde sınıfın her alanı için değişken tanımladıktan sonra “Cep_Fatura” adı verilen sınıftan yararlanarak new anahtar kelimesi ile aşağıdaki gibi nesne hazırladık ve alanların içeriklerini ekrana yazdık. 

using System;
namespace Deneme

 class Ana_sinif 
 
  public static void Main() 
  
     Cep_Fatura F1; 
     F1 = new Cep_Fatura(); 
     Console.WriteLine(F1.Sahip); 
     Console.WriteLine(F1.Numara); 
     Console.WriteLine(F1.Adres); 
     Console.WriteLine(F1.Tutar); 
 
 }

public class Cep_Fatura 
 
    public string Sahip; 
    public string Numara; 
    public string Adres; 
    public int Tutar; 
  }


Bu konsol uygulaması derlenip çalıştırıldığında ekrana önce 3 kez boşluk ardından 0 yazılır. Çünkü new anahtar kelimesi ile nesne hazırlanırken varsayılan yapıcı metot sayesinde sınıfın string tipindeki alanlarının başlangıç içerikleri boşluk ve int tipindeki alanın başlangıç içeriği ise 0 olarak ayarlanır. Şimdi bu alanlara bilgi aktarıp ondan sonra içeriklerini yazdıracağız. 

public static void Main() 
 
   Cep_Fatura F1 = new Cep_Fatura(); 
   F1.Sahip = "Seçkin Yayıncılık"; 
   F1.Numara = "0-533-770 50 99"; 
   F1.Adres = "Sağlık Sok No:19/B"; 
   F1.Tutar = 255000000; 
   Console.WriteLine(F1.Sahip); 
   Console.WriteLine(F1.Numara); 
   Console.WriteLine(F1.Adres); 
   Console.WriteLine(F1.Tutar);


Burada yapılan, bir formun Text özelliğinde değişiklik yapmaktan farklı değildir. Main() metodu bu şekilde düzenlenen konsol uygulaması çalıştırıldığında “Cep_Fatura” sınıfından yola çıkarak hazırlanan nesnenin alanlarına aktarılan bilgiler ekrana yazılır. 

Yukarıda “Cep_Fatura” adı verilen sınıftan yola çıkarak “F1” adında bir nesne hazırladık ve bu nesnenin alanlarına bilgi aktarıp içeriklerini ekrana yazdık. İstediğiniz sınıftan istediğiniz sayıda nesne oluşturabilirsiniz. Aşağıda verilen 2 satır ile “F2” adında 2. bir nesne hazırlanır. 

Cep_Fatura F2;
F2 = new Cep_Fatura(); 

Normalde programcılar sabit bilgileri veritabanına yazıp gerek duyduklarında bu bilgileri veritabanından okuyup nesnenin alanlarına veya özelliklerine aktarırlar. Burada veritabanı hazırlayıp işlemleri ona göre yapma imkanımız olmadığına göre gerekli bilgileri ya doğrudan koda yazıyoruz ya da ReadLine() metodu ile kullanıcıdan istiyoruz. Şimdi kullanıcıdan cep telefonu faturasının ayrıntılarını isteyeceğiz. Bu amaçla “Cep_Fatura” adını verilen sınıfta Toplam() adında bir metot hazırladık. 

public int Toplam() 
 
   int Konusmalar, Mesajlar, Diger; 
   Console.Write("Konuşma tutari :"); 
   Konusmalar = Int32.Parse(Console.ReadLine()); 
   Console.Write("Mesaj tutari :"); 
   Mesajlar = Int32.Parse(Console.ReadLine()); 
   Console.Write("Diğer tutarlar :"); 
   Diger = Int32.Parse(Console.ReadLine()); 
   return Konusmalar + Mesajlar + Diger;


Bu metotta önce int tipinde 3 değişken tanımladık. Ardından bu değişkenlere aktarmak üzere kullanıcıdan bilgi girmesini istedik. Kullanıcın girdiği 3 bilgiyi toplayıp geriye gönderdik. Bu metot tarafından geriye gönderilen bilgi “Cep_Fatura” adını verdiğimiz sınıftan yola çıkılarak oluşturulan nesnenin “Tutar” özelliğine aktarılacaktır.



Bu amaçla konsol uygulamasının Main() metodunu yandaki gibi değiştirdik. İşaret edilen satır sayesinde F1 nesnesi için Toplam() adlı metot işletilir ve bu metodun geriye gönderdiği değer aynı nesnenin “Tutar” alanına aktarılır.  

Şimdi “Cep_Fatura” adını verdiğimiz sınıf için hazırlayacağımız yapıcı metot dahilinde telefon sahibinin adı, adresi ve numara kullanıcıdan istenecek. 

public Cep_Fatura() 
 
   Console.Write("Telefonun Sahibi :"); 
   Sahip = Console.ReadLine(); 
   Console.Write("Fatura adresi :"); 
   Adres = Console.ReadLine(); 
   Console.Write("Telefon no :"); 
   Numara = Console.ReadLine(); 
 

Bu metot sınıf ile aynı ada sahip olduğu için new anahtar kelimesi ile nesne hazırlandığı zaman otomatik olarak işletilerek kullanıcıdan bu bilgileri girmesi istenir. Bu şekilde yapıcı metodu hazırladıktan sonra Main() metodunu aşağıdaki gibi değiştirdik.



Şimdi ise F1 adını verdiğimiz nesnenin özelliklerinin içeriğini ekrana yazan satırları “Cep_Fatura” sınıfı içinde ayrı bir metot olarak düzenleyeceğiz. Bu amaçla “Yaz()” adında bir metot hazırladık. 

public void Yaz() 
 
   Console.WriteLine(F1.Sahip); 
   Console.WriteLine(F1.Numara); 
   Console.WriteLine(F1.Adres); 
   Console.WriteLine(F1.Tutar); 
 

“Cep_Fatura” sınıfı içinde hazırlamış olmamıza rağmen ilk sınıfta yer alan bu metodu Main() metodu içinde burada yapıldığı gibi çağırırsanız hata meydana gelir. Hata meydana gelmesine neden olan satırı aşağıda görebilirsiniz. 

public static void Main() 
 
   Cep_Fatura F1 = new Cep_Fatura(); 
   F1.Tutar = F1.Toplam(); 
   F1.Yaz();  // hata meydana gelir 
 }

Gerçekte hataya neden olan satır bu satır değildir. Hataya neden olan satırlar “Yaz()” metodundaki satırlardır. Çünkü F1 nesnesi konsol uygulamasındaki ilk sınıftan yola çıkılarak hazırlanmış olmasına rağmen diğer sınıfta kullanılmak istenmektedir. Bu hatanın önüne geçmek için Yaz() metodunda kullanılan F1 yerine this anahtar kelimesi kullanılmalıdır. Burada kullanılan this, içinde bulunulan sınıfı temsil etmektedir. 

public void Yaz() 
 
   Console.WriteLine(this.Sahip); 
   Console.WriteLine(this.Numara); 
   Console.WriteLine(this.Adres); 
   Console.WriteLine(this.Tutar); 
 

Partial(Parçalı) Classlar 

C# derleyicisi sınıfların birden fazla dosya olarak düzenlenmesine izin vermektedir. Partial Class adı verilen bu özellik .NET Framework 2.0 ve C# 2.0 ile desteklenmeye başlandı. Partial sınıfların nasıl hazırlandığına örnek olması için aşağıda aynı kod dosyası içinde aynı ada sahip 2 basit sınıf hazırladık.



Benzer şekilde aynı CS dosyası içinde aynı ada sahip 3. bir sınıfı hazırlamak mümkündür. Şimdi yukarıda hazırlanan örnekteki 2. sınıfı başka bir CS dosyasına taşıyacağız.



Derleme sırasında 2 Class birleştirildiği için 2. sınıftaki metodu herhangi bir hazırlık yapmadan ilk sınıfta kullandık. Bu şekilde 2 CS dosyasından meydana gelen konsol uygulaması derlenirken komut satırı aşağıdaki gibi düzenlenmelidir.



.NET Framework 1.1 ve C# 1.0 parçalı Class’ları desteklemediği için Visual Studio 2003 ile hazırlanan projelerdeki formlarla ilgili bütün bilgiler tek dosyada toplanırdı. Visual Studio 2005 ve 2008’de ise projeye bir form eklendiği zaman Form sınıfından türetilen Class’la ilgili toplam 3 dosya hazırlanmaktadır. Bu 3 dosya derleme sırasında bileştirilmektedir.

Özellikler – Properties 

Bir alanın içeriği kontrol edilmeden değiştirildiğinde sorunlar yaşanabilir. Bunun önüne geçmenin yolu, kullanıcının seçimini değerlendirip ona göre işlem yapmaktır. Örneğin veritabanında kayıtlı bir stokun miktarının direk değiştirilmesine izin verilmez. Stok miktarı ancak giriş ve çıkış işlemleri sonucu değişsin istenir. Tekrar etmek gerekirse, Class’ın bazı üyelerine başka sınıflardan doğrudan erişime izin verilmesi sorunlara neden olabilir. 

Daha önceki konulardan bildiğiniz gibi Toolbox’tan yararlanılarak forma yerleştirilen nesnelerin bir çok özelliğini Properties penceresinde değiştirmek mümkündür. Ancak bazı özellikleri kod yazarak çalışma anında değiştirmek mümkün değildir. Ayrıca bazı özelliklere aktarılabilinen değerlerin belli sınırlar içinde olması istenir. Örneğin ProgressBar nesnesinin Value özelliğine Maximum özelliğinin içeriğinden daha büyük ve Minimum özelliğinin içeriğinden daha küçük değer aktarılamaz. 

Benzer durum kendi hazırladığınız sınıflarda karşınıza çıkar. Bu konuda bilgi vermek için yukarıda verdiğimiz “Cep_Fatura” adlı sınıfın kısıtlı bir versiyonunu hazırladık. Bu konsol uygulamasında yine “Ana_sinif” ve “Cep_Fatura” adında 2 sınıf olacaktır.



Bu koddaki “Cep_Fatura” sınıfına yakından baktığınızda “Sahip” ve “Numara” adında 2 alanın olduğunu görebilirsiniz. Sınıfın alanlarına bazen özellik denilmektedir. Çünkü özellikler genellikle alanlara bağlı olarak işlev görmektedir. 

“Cep_Fatura” adı verilen sınıfın alanlarına bilgi aktarma işlemini yukarıdaki sayfalarda sınıfın yapıcı metodu ile yaptık. Ancak bu örnekte sınıfın elemanlarına bilgi aktarma işlemini nesneyi new anahtar kelimesi ile hazırladıktan sonra Main() metodu içinde yaptık. 

“Cep_Fatura” adını verdiğimiz sınıfın “Sahip” ve “Numara” alanları public oldukları için başka sınıflardan bu alanlara istenildiği gibi bilgi aktarılabilinir. Bu alanlara aktarılmak üzere kullanıcıdan istenen veya kullanıcının girdiği bilgiyi Main() metodu içinde kontrol edip bilginin uygun olup olmadığını araştırabilirsiniz. Ancak bu işlemi başka bir sınıfın içinde yapmak pratik değildir. Bu nedenle başka bir sınıftan doğrudan erişilmesine izin verilmek istenmeyen alanlar olarak private ayarlanır. 

Yukarıda verilen konsol uygulamasında “Cep_Fatura” sınıfının “Sahip” ve “Numara” alanlarının önündeki public silinip yerine private yazılırsa hata meydana gelir. Çünkü başka sınıflara kapatılan veya başka sınıfların dahilinde değiştirilmesine izin verilmeyen alanlarının içeriği değiştirilmeye çalışılmaktadır. 

Buradaki amacımız bu alanlara başka sınıflardan erişimi tümden engellemek değildir. Amaç bu alanlara aktarılacak bilgiyi kontrol edebilmektir. Örneğin telefon numarasının belli sayıda rakama sahip olup olmadığını kontrol etmektir. Yukarıda denildiği gibi bu kontrolü başka sınıfta yapmak mümkündür ancak pratik değildir. Sınıfın hangi alanı kontrol edilmek isteniyorsa o alan için özellik tanımlanmalıdır. Özelliklerde get ve set blokları olmaktadır. Şimdi “Cep_Fatura” adını verdiğimiz sınıfın “Numara” adlı alanı için bir özellik tanımlayacağız. Bu amaçla alanın önündeki public deyimini silip yerine private yazdık. 

public class Cep_Fatura 
   
   
public string Sahip; 
   private string Numara; 
   public void Yaz() 
      
      Console.WriteLine(this.Sahip); 
      Console.WriteLine(this.Numara); 
   
 
}
 

Bu şartlarda “Cep_Fatura” sınıfının “Numara” alanına başka sınıflardan erişip içeriğini okumak veya değiştirmek mümkün değildir. Çünkü bu alan artık sınıfa özel bir alandır. Private alanlara başka sınıflardan erişebilmek için söz konusu alan için özellik tanımlamak veya özel işlevi olan metot hazırlamak gerekmektedir. Yukarıda belirtildiği gibi erişimci metot adı verilen bu tür metotlarda get ve set blokları olmaktadır. Özelliğe istediğiniz adı verebilirsiniz. Ancak özelliğe ilgili alanı çağrıştıran bir ad vermeniz önerilir. Bu özel metodu(erişimci) veya özelliği hazırlama amacımıza uygun olarak özelliğe “Numara_kontrol” adını verdik. 

public class Cep_Fatura 
 
   public string Sahip; 
   private string Numara;
   public string Numara_kontrol 
    
       get 
         
         
      set 
       
       }           
   

Sınıfın private alanına hizmet edecek özelliğin public olması gerekir. Yoksa özelliği kullanmak mümkün olmaz. Ayrıca erişimci adı verilen bu özel metot hangi tipteki alana hizmet edecekse alanın tipini belirten anahtar kelime özellik adından önce yazılmalıdır. set bloğunda ilgili alana değer aktarılmakta ve get bloğunda ise alanın içeriği okunmaktadır.



Henüz set ve get bloklarında alana değer aktarma ve okuma işlemini yapmadığımız için bu şartlarda uygulama derlenirse hata meydana gelir. Alan için özellik tanımlandıktan sonra nesne hazırlanıp nesnenin bu elemanına bilgi aktarılmak veya elemanın içeriği okunmak istendiğinde alan yerine alanı temsil edecek özelliğin adı kullanılmalıdır. Özellikler public olduğu için her sınıfta kullanılabilir. 

Buradaki F1.Numara_kontrol=Console.ReadLine() satırı ile özelliğe bilgi aktarılmaktadır. Ancak henüz bu özelliğin hangi alanı temsil ettiği veya hangi alana hizmet ettiği belli değildir. Tanımladığınız özelliğin veya özel işlevi olan metodun hangi alanına hizmet edeceği get ve set blokları içinde belirtilir. Bu işlemin nasıl yapıldığını aşağıda görebilirsiniz. 

Get 
 
   return Numara; 
 }
set 
 
   Numara =value; 
 }         

Burada value değişkenin içeriği alana aktarılmaktadır. Burada kullanılan value değişkenin içeriği nesne hazırlanırken özelliğe aktarılan bilgidir. Bizim örnekte nesne(F1 adını vermiştik) hazırlandıktan sonra F1.Numara_kontrol=Console.ReadLine() satırı sayesinde kullanıcının girmiş olduğu bilgi value değişkenine aktarılmaktadır. get bloğunda ise bu alanın mevcut içeriği geriye gönderilmektedir. 

Buraya kadar anlatılanların açıklaması şudur: “Numara” adlı alan private olduğu için başka sınıfların içinden erişemiyorduk. Bu engeli aşmak için özellik tanımladık. Hemen soracaksınız; bu hali ile set ve get bloklarını kullanmanın herhangi bir yararı oldu mu? Şimdilik hayır. Şimdi kullanıcının alana aktaracağı telefon numarasının uzunluğunu kontrol edeceğiz. 

public string Numara_kontrol 
 
  get 
   
     return Numara; 
   
  set 
  
     string N = value; 
     int uzunluk = N.Length; 
     if (uzunluk < 11) 
       Console.WriteLine("Telefon Numarası eksik"); 
     else 
       Numara =value; 
   }
}        

set
bloğuna yazılan bu satırlar sayesinde nesne hazırlanıp özelliğe aktarılan telefon numarasının rakam sayısı (string bilginin uzunluğu) öğrenilmektedir. Bilginin uzunluğu 11’den küçükse mesaj verilip girilen bilgi nesnenin alanına aktarılmamaktadır. 

Konunun iyice anlaşılmasını sağlamak için “Cep_Fatura” sınıfındaki “Sahip” adlı 2. alan için özellik tanımlayacağız. Bu özellik sayesinde kullanıcının girdiği ad bilgisi String sınıfının ToUpper() metodu ile büyük harflere çevrilecektir. 

public class Cep_Fatura 
 
  private string Sahip; 
  private string Numara;
  public string Sahip_kontrol 
   
    get 
     
      return Sahip; 
    
    set 
    
      Sahip=value.ToUpper(); 
   
   }  
 public string Numara_kontrol 
 
   get 
    
      return Numara; 
    
  set 
  
     string N = value; 
     int uzunluk = N.Length; 
     if (uzunluk < 11) 
      Console.WriteLine("Telefon Numarası eksik"); 
    else 
     Numara =value; 
  }


Benzer şekilde sınıftaki her alan için özellik tanımlayabilirsiniz. Bazen alanların içeriğinin okunmasına izin verilir ama değiştirilmesi engellenmek istenir. Hazırladığınız sınıfta içeriğinin okunmasına izin verip değiştirilmesini engellemek istediğiniz alanlar varsa söz konusu alan için hazırladığınız özelliğin set bloğunu yazmamanız gerekir. Bu ayarlamanın nasıl yapıldığını anlatmak için “Cep_Fatura” adını verdiğimiz sınıfa “Kod” adında 3. bir alan ekledik ve bu alana ilk değer aktardık. 

public class Cep_Fatura 
 
   private string Sahip; 
   private string Numara; 
   private string Kod = "0-312"; 

Bu alan private olduğu için içeriğine başka sınıflardan erişebilmek için bu alan için özellik veya erişimci metot hazırlamak gerekir. Amacınız yalnızca alanın içeriğini okumaksa özellikte set kısmını yazmayıp get kısmını aşağıdaki gibi yazmalısınız. 

public string Kod_kontrol 
 
  get 
   
       return Kod; 
   
 

Bu örnekte “Kod” alanını tanımlarken ilk değer aktardık. Bu alana sınıfın içinde değer aktarabilirsiniz. Ancak özelliğin set kısmı olmadığı için başka sınıflarda iken sınıftan nesne hazırlandığı zaman nesnenin “Kod “adı verilen alanın içeriği değiştirilemez. 

Yukarıda özelliklerden söz ederken her özelliğin get ve set bloklarına sahip olduğunu belirtik. C# derleyicisinin nazarında set ve get blokları gerçekte ayrı birer metottur. Kolaylık olsun diye bu 2 metodun özelliğe ait bloğun içinde yer almasına izin verilmektedir. Bu konuda bilgi vermek için yukarıda get ve set bloklarını kullanarak hazırladığımız örneği aşağıdaki gibi değiştirdik. Ancak özellikleri bu şekilde kullanmak pratik değildir. 

using System;
class Ana_Sinif 
 
   public static void Main() 
   
      Cep_Fatura F1; 
      F1 = new Cep_Fatura(); 
      Console.Write("Telefonun sahibi:"); 
      F1.Sahip = Console.ReadLine(); 
      Console.Write("Telefon No:"); 
      F1.set_Numara_kontrol(Console.ReadLine()); 
      F1.Yaz(); 
   
 }
class Cep_Fatura 
 
   public string Sahip; 
   private string Numara; 
   public string get_Numara_kontrol() 
    
      return Numara; 
   
  public void set_Numara_kontrol(string value) 
   
      Numara=value; 
    
  public void Yaz() 
   
      Console.WriteLine(this.Sahip); 
      Console.WriteLine(this.get_Numara_kontrol()); 
   
 

Kalıtım Kavramı 

Yeni bir sınıf hazırlarken mevcut sınıfların özelliklerinden, olaylarından ve metotlarından yararlanabilirsiniz. Daha önceki konulardan bildiğiniz gibi Visual Studio ile C# projesi hazırladığınızda “Form1” adında bir Class hazırlanmaktadır. 

 
public partial class Form1 : Form 
  
     public Form1() 
     
        InitializeComponent(); 
     
  

Visual Studio tarafından hazırlanan “Form1” adlı Class’ın deklare edildiği ilk satırda Class adından sonra özellikleri, olayları, metotları vs. her şeyi miras alınmak istenen Class’ın adı yazılmaktadır. Miras veren ile miras alan class’lar “:” ile birbirinden ayrılmaktadır. 

“System.Windows.Forms” adlı namespace’te bulunan Form class’ı çok sayıda metoda, olaya ve özelliğe sahip olduğu için yukarıdaki satırlarla hazırlanan “Form1” sınıfı çok sayıda metoda, özelliğe ve alana sahip olur. Kalıtım kavramı hakkında adım adım bilgi vermek için önce aşağıdaki gibi basit konsol uygulaması hazırladık. 

using System;
class Aritmetik 
 
   public static int Toplama(int i, int j) 
   
       return i +j; 
   
   public static int Carpma(int i, int j) 
   
      return i +j; 
   
 }
class Ana_sinif : Aritmetik 
 

  public static void Main() 
  
     int Sonuc = Toplama(100, 200); 
     Console.WriteLine(Sonuc);       
  
 

Bu kodda önce 2 static metoda sahip “Aritmetik” adında bir class hazırladık. Ardından “Ana_sinif” adında 2. bir sınıf hazırladık. Bu sınıfın adından sonra “Aritmetik” sınıfının adını yazdığımız için Aritmetik sınıfının metotları ve özellikleri Ana_sinif’ta kullanılabilir. Bu nedenle bu uygulama derlenip çalıştırıldığında hata vermez ve ekrana 300 yazılır. 

Hazırladığınız sınıfın mirasının alınmasını veya türetilmesini engellemek istiyorsanız o sınıfı sealed sınıf yapmalısınız. Bütün metotları statik olan sınıfları türetmek anlamlı olmadığı için sealed sınıf olarak ayarlanabilir. Sealed olarak işaret edilen sınıf herhangi bir sınıfın ana sınıfı yapılmak istendiğinde hata meydana gelir. 

sealed class Aritmetik 
   
    public static int Toplama(int i, int j) 
   
      return i +j; 
   
 }

class Ana_sinif : Aritmetik // Hata meydana gelir.
 
  public static void Main() 
  
     int Sonuc = Toplama(100, 200); 
     Console.WriteLine(Sonuc);       
  
 

.NET Framework’te bütün sınıflar Object sınıfından türetilmektedir. Bu nedenle aşağıda verilen 2 sınıf hazırlama örneği birbirinden farklı değildir. 

class Mesaj : Object 
 
  }      

Class Mesaj 
 
 

Statik Sınıflar 

Bu bölümün ilk sayfalarında belirtildiği gibi statik metotları işletmek için söz konusu metodun tanımlı olduğu sınıftan yola çıkarak nesne hazırlamak zorunda değilsiniz. Bu konuda bilgi vermek için aşağıda verilen basit örneği hazırladık. 

class Aritmetik 
 
   public static int Toplama(int i, int j) 
   
      return i +j; 
    
  }
class Ana_sinif 
 
  public static void Main() 
  
     int Sonuc; 
     Sonuc = Aritmetik.Toplama(100,200); 
     System.Console.WriteLine(Sonuc); 
  
 

Bu örnekte Toplama() adını verdiğimiz static bir metot var. Bu metot statik dolduğundan kullanmak için nesne hazırlamaya gerek yoktur. Bu sınıftan yola çıkılıp nesne hazırlanabilir ama statik metotlar aşağıdaki gibi işletilemezler. 

class Ana_sinif 
 
  public static void Main() 
  
      Aritmetik Nesne; 
      Nesne = new Aritmetik(); 
      int Sonuc = Nesne.Toplama(10,20); // Hata meydana gelir. 
   
 

Sınıflarda statik metotlar olduğu gibi statik alanlar da olabilir. Statik alanlar, diğer programlama dillerindeki global değişkenler gibi işlev görebilirler. Başka bir deyişle statik alanlar, ilgili sınıfın bütün kopyaları tarafından ortak olarak kullanılan alanlardır. Bu konuda bilgi vermek için aşağıda verilen kodu yazdık. 

using System;
class Katsayilar 
 
   public static float kdv = 0.18f; 
 }
class Ana_sinif 
 
  public static void Main() 
  
     float fiyat = 1500; 
     float kdv_dahil; 
     kdv_dahil = fiyat * (1+Katsayilar.kdv); 
     Console.WriteLine(kdv_dahil); 
   
 

Hem public hem static olan “kdv” adlı değişken veya alan uygulamadaki bütün sınıflarda yaşadığı için içeriği kullanılabilinir veya değiştirilebilir. Statik alanların veya değişkenlerin özellikleri hakkında bilgi vermek için bu uygulamaya ekleme yaptık. Başka sınıfta tanımlı olan static alanın içeriğini değiştirip ondan sonra kullandık. 

public static void Main() 
 
   float fiyat = 1500; 
   float kdv_dahil; 
   kdv_dahil = fiyat * (1+Katsayilar.kdv); 
   Console.WriteLine(kdv_dahil); 
   fiyat = 2250; 
   Katsayilar.kdv =0.008f; 
   Kdv_dahil = fiyat * (1+Katsayilar.kdv); 
   Console.WriteLine(kdv_dahil); 
 

Yukarıda belirtildiği gibi statik metot, alan ve özellik içeren sınıfların örnekleri alınabilmektedir. Ancak bu metotların ve alanların sınıftan türetilen nesneyle bağlantılı olarak kullanılması mümkün olamamaktadır.

Hazırlamak istediğiniz sınıfın bütün alanlarının ve metotlarının static olmasını istiyorsanız sınıfın static olmasını sağlayabilirsininiz. Statik sınıflar hakkında bilgi vermek için aşağıda verilen basit kodu hazırladık. 

static class Katsayilar 
 
   public static float kdv = 0.18f; 
 }
class Ana_sinif 
 
   public static void Main() 
    
      Katsayilar Nesne = new Katsayilar(); // Bu satır hataya neden olur. 
    
 

“Katsayilar” adını verdiğimiz class static olduğu için new anahtar kelimesi ile örneği hazırlanamaz. Bu nedenle bu kod işletildiğinde hata meydana gelir. Benzer şekilde static sınıfta static olmayan alanların ve metotların olmasına izin verilmez. Bu nedenle static sınıf aşağıdaki gibi düzenlendiğinde hata meydana gelir. 

static class Katsayilar 
 
   public float kdv = 0.18f; // Hata meydana gelir. 
 

new
anahtar kelimesi ile static sınıfların örnekleri alınıp nesne hazırlanamadığı için yapıcı metot içeremezler. Bu nedenle aşağıda verilen kod hataya neden olur. 

static class Katsayilar 
 
   public static float kdv = 0.18f; 
   public static Katsayilar(); // Bu metot hataya neden olur 
    
    
 

Ayrıca statik sınıflar başka sınıfların temel sınıfı veya başka bir sınıfın mirasçısı olamazlar. Başka bir deyişle statik sınıflardan başka sınıflar türetilemez. Bu nedenle aşağıda verilen kod hataya neden olur. 

static class Katsayilar 
 
  }
class Mirasci : Katsayilar// Hata meydana gelir 
 
 

Türetilemeyen ve örneği alınamayan statik sınıflar başka statik sınıfları içerebilirler. Uygulama dahilinde kullanılan statik sınıflar .NET Runtime tarafından otomatik olarak yüklenmekte ve kullanıma hep hazırdırlar. 

Yapıcı Metotlar 

Hazırladığınız sınıf statik değilse ondan yararlanabilmeniz için new anahtar kelimesi ile sınıftan nesne üretmeniz gerekiyor. Sınıflardan yola çıkılarak nesne hazırlanırken kullanılan metotlara yapıcı metot veya Constructor adı verilmektedir. C# derleyicisinin standart yapıcı metodunu kullanmak yerine kendi yapıcı metodunuzu hazırlayabilirsiniz. 

Sınıfınız için yapıcı metot hazırlamak istiyorsanız bu metot sınıfla aynı ada sahip olmalıdır. Yapıcı metotlar geriye değer göndermemelerine rağmen void olarak işaret edilmezler.  Yapıcı metotlar public’tir. Çünkü bu metotlar doğal olarak başka sınıflardan çağrılırlar. 

using System;
class Sinif_1 
   
 
 public Sinif_1() 
    
      Console.WriteLine("nesne hazırlandı"); 
    
  public static void Main() 
  
     Sinif_1 nesne_1; 
     nesne_1 = new Sinif_1();        
   
 

Bu uygulama derlenip çalıştırıldığında ekrana “nesne hazırlandı” mesajı yazılır. Yapıcı metotlar hakkında bilgi verebilmek için tarihsel bilgiler üzerinde işlem yapan bir sınıf hazırlayacağız. Bu amaçla 2 sınıf içeren bir konsol uygulaması hazırladık. 

using System;
class Tarih_class 
 
   public int Gun; 
   public int Ay; 
   public int Yil; 
 }
class Ana_sinif 
 
  public static void Main() 
   
   
 

2 sınıfının bulunduğu bu uygulamada “Tarih_class” adını verdiğimiz ilk sınıf 3 public alana sahiptir. Bu şartlarda 2. sınıftaki Main() metodunda bu sınıftan yola çıkılıp nesne hazırlanıp alanların içerikleri ekrana yazıldığında her 3 alanın da 0 olduğu görülür. Bu şartlarda derleme yapıldığında derleyici “Tarih_class” adlı ilk sınıfın alanlarına ilk değer aktarılmadığı ve bu nedenle defualt değerlerin aktarıldığı konusunda 3 uyarı mesajı listeler. 

class Tarih_class 
 
   public int Gun; 
   public int Ay; 
   public int Yil; 
 }
class Ana_sinif 
 
  public static void Main() 
  
     Tarih_class Tarih = new Tarih_class(); 
     Console.WriteLine(Tarih.Gun); 
     Console.WriteLine(Tarih.Ay); 
     Console.WriteLine(Tarih.Yil); 
  
 

Şimdi ise “Tarih_class” adlı sınıf için yapıcı metot hazırlayacağız. Hazırlayacağımız yapıcı metodun bir işlevi olmayacak ve sınıfın int tipindeki 3 alanına sıfır(0) aktaracağız. 

class Tarih_class 
 
   public int Gun; 
   public int Ay; 
   public int Yil; 
   public Tarih_class() 
    
      Gun = 0; 
      Ay = 0; 
      Yil = 0; 
    
   

Bu sınıf bu şekilde değiştirilip uygulama derlendiğinde uyarı mesajları verilmez ve ekrana 3 kez 0 yazılır. Şimdi bu sınıfın yapıcı metoduna değiştirip gün, ay ve yıl bilgilerinin sistem saatinden alınmasını sağlayacağız. 

class Tarih_class 
 
   public int Gun; 
   public int Ay; 
   public int Yil; 
   public Tarih_class() 
   
      DateTime Bugun; 
      Bugun = DateTime.Today; 
      Gun = Bugun.Day; 
       Ay = Bugun.Month; 
       Yil = Bugun.Year; 
    
 

Bu şartlarda konsol uygulaması derlenip çalıştırıldığında sistem saatinden günün tarihi alınıp gün, ay ve yıl şeklinde ayrıştırılıp ekrana yazılır. Şimdi ise 2. bir yapıcı metot hazırlayacağız. C# derleyicisi yapıcı metotların overload versiyonlarını desteklediği için aynı sınıf için değişik sayı ve tipte parametreye sahip birden fazla yapıcı metot hazırlayabilirsiniz. Ayrıca yapıcı metotlara dizi değişkenleri parametre olarak verebilirsiniz. 

class Tarih_class 
 
   public int Gun; 
   public int Ay; 
   public int Yil; 
   public Tarih_class() 
   
      DateTime Bugun; 
      Bugun = DateTime.Today; 
      Gun = Bugun.Day; 
      Ay  = Bugun.Month; 
      Yil = Bugun.Year; 
   
   public Tarih_class(int i) 
   
      DateTime Bugun; 
      Bugun = DateTime.Today; 
      Gun = i; 
      Ay  = Bugun.Month; 
      Yil = Bugun.Year; 
   
 

Burada hazırladığımız ilk yapıcı metot herhangi bir parametreye sahip değilken, ikincisi int tipinde bir parametreye sahiptir. Bu nedenle bu sınıftan yola çıkıp nesne hazırlanırken sınıfın yapıcı metoduna int tipinde bir değer parametre olarak verilirse 2. yapıcı metot işletilir. “Tarih_class” sınıfından yararlanılıp aşağıdaki gibi bir nesne hazırlanırsa ekrana önce 25, sonra geçerli tarihin ay ve yıl bilgileri yazılır. 

class Ana_sinif 
 
   public static void Main() 
   
      Tarih_class Tarih = new Tarih_class(25); 
      Console.WriteLine(Tarih.Gun); 
      Console.WriteLine(Tarih.Ay); 
      Console.WriteLine(Tarih.Yil); 
   
 

Konunun iyice anlaşılmasını sağlamak için “Tarih_class” sınıfı için 3. bir Constructors metot hazırlayacağız. Bu metot 2 parametreye sahip olacağı için nesne hazırlanırken yapıcı metoda int tipinde 2 parametre verildiği zaman işe yarar. 

public Tarih_class(int i, int j) 
 
   DateTime Bugun; 
   Bugun = DateTime.Today; 
   Gun = i; 
   Ay  = j; 
   Yil = Bugun.Year; 
 

Yukarıda belirtildiği gibi yapıcı metotlara dizi değişkenleri parametre olarak vermek mümkündür. Bu konuda bilgi vermek için bir örnek hazırladık. Hazırladığımız örnekte yapıcı metoda parametre olarak verilen dizi değişkenin elemanları konsola yazılacaktır. 

namespace Deneme

 class Sinif_1 
 
    public static void Main() 
    
       string[] Dizi = new string[3]; 
       Dizi[0]="Fenerbahçe"; 
       Dizi[1] = "Galatasaray"; 
       Dizi[2] = "Beşiktaş"; 
       Sinif_2 nesne = new Sinif_2(Dizi); 
       Console.WriteLine("Devam etmek için bir tuşa basın"); 
       Console.ReadLine(); 
    
   }
class Sinif_2 
 
   public Sinif_2(string[] Dizi) 
   
      int sayi = Dizi.Length; 
      for (int i=0; i<sayi; i++) 
        Console.WriteLine(Dizi[i]); 
   
  }


Destructor – Yok Edici Metotlar 

Yukarıdaki sayfalarda işaret edildiği gibi new anahtar kelimesi ile sınıfın örneği alınan sınıfın Constructor adı verilen metodu varsa işletiliyor. Sınıfın yapıcı metodu yoksa derleyici tarafından otomatik olarak hazırlanan varsayılan yapıcı metot işletilmektedir. Benzer şekilde hazırlanan nesne Garbage Collector tarafından bellekten silinirken sınıfın Destructor metodu varsa işletilmektedir. Bu konuda bilgi vermek için aşağıda verilen kodu hazırladık. 

class Mesaj 
 
  public Mesaj() 
  
    Console.WriteLine("Mesaj Sınıfının örneği Hazırlandı"); 
  

   
~Mesaj() 
    
     Console.WriteLine("Nesne bellekten Silinecek"); 
  
 }
class Ana_sinif 
 
  public static void Main() 
  
     Mesaj Nesne = new Mesaj(); 
     Console.WriteLine("Çıkmak için bir tuşa basın"); 
     Console.ReadLine(); 
  
 

Bu kodda sizin için yeni olan “~” ile başlayan ve Class ile aynı ada sahip olan metottur. Eğer söz konusu sınıf için Destructor metot hazırlamak istiyorsanız metot sınıfla aynı ada sahip olmalı ve adının önüne tilda(“~”) karakteri yazılmalıdır. Destructor metotların parametreleri yoktur ve geriye bilgi göndermezler. 

Bu uygulama derlenip çalıştırıldığında new anahtar kelimesi ile “Mesaj” adlı class’ın örneği hazırlandığında bu class’ın yapıcı metodu işletilir. Devamında sıra uygulamanın çalışmasını durdurmak için yazılan Console.ReadLine(); satıra gelir. Aşağıda verilen ekran görüntüsü bu konsol uygulamasının işletimi bu satırda iken alındı.



Bu sırada bir tuşa basılıp uygulamanın işletimi sona erdirildiğinde “Mesaj” adını verdiğimiz ilk sınıfın yok edici metodu işletilir. Aşağıda verilen ekran görüntüsünü bir tuşa basıp uygulamanın çalışmasını sona erdirdikten sonra aldık.



Hemen anlatmak gerekirse C# uygulaması dahilinde hazırlanıp artık işlevleri olmayan nesneler Garbage Collector(Gereksiz Nesne Toplayıcısı) tarafından zaman zaman bellekten temizlenmektedir. Böylece programcı gerek duymadığı nesneleri temizlemek zorunda kalmıyor. Hazırlayıp kullandığınız ancak artık gerek duymadığınız nesnelerin bellekten hemen temizlenmesini istiyorsanız Garbage Collector’ü kendiniz devreye sokabilirsiniz.

C# 3.0 Kitabı 25.11.2009 20:03:42

4 YORUM


YorumlarYorum Yaz
Ana Sayfa | Hakkımda | Kitap Önerileri | Fotoğraflarım | RSS | İletişim
Memik Yanık 2004-2009 © Tüm Hakları Saklıdır.
Hazırlayan www.semgoksu.com