Metotlar ve Fonksiyonlar
- Nesneye yönelik programlama dillerinde genellikle fonksiyonlar “metot” olarak isimlendirilirler. Metot ve fonksiyon olarak ifade edilecek kavramlar aynı anlamda kullanılacaktır.
- Her çalışan C# programı bir ana fonksiyona (Main) sahiptir. Program çalışmaya bu fonksiyondan başlar.
- Tüm kodların bu fonksiyon içine yazılması çok uygun olmaz.
Metot Kavramı
- Programın herhangi bir yerinde kullanmak için belirli bir işi yerine getirmek amacıyla tasarlanmış alt programlara metot denir.
- Metotlar tek başlarına çalıştırılabilen yapılar değildir.
- Metot, metodu çağıran ana program için faydalı işler yapar.
- Metodun iş yapması için kendisini çağıran metottan aldığı bilgilere parametre(argüman), kendisini çağıran fonksiyona döndürdüğü bilgiye ise geri dönüş değeri (return value)
Metot Bildirimi
- C#’ta bildirilen bütün metotlar mutlaka bir sınıfın içinde olmalıdır. Bir sınıfın üyesi olmayan metotlar bildirilemez. Metotları tanımlarken kullanılan bildirim şu şekildedir:
- *erişim belirteçleri+ metot ismi (parametre listesi)
- {
- metot gövdesi;
- }
- Erişim belirteçleri (public, private..) metoda nerelerden erişilebileceğini ayarlar. Belirtilmediği durumlarda “private” olarak kabul edilir. Yani sadece tanımlandığı sınıf içinde kullanılabilen bir metot olur.
- Geri dönüş değeri, metodun çağıran fonksiyona gönderdiği veririn türüdür.
- Parametreler ise metodun çalışırken ihtiyaç duyduğu çağıran fonksiyondan gönderilen bilgileridir.
- Örn:
- int MetotAdi(int a,int b)
- { return a+b; }
- C#’ta bir metot kullanılacaksa metodun içinde bulunduğu sınıf türünden bir nesne tanımlanır ve ‘.’ operatörü ile metot çağrılır.
- using System;
- class Metotlar
- {
- int Topla(int a,int b)
- {
- return a+b;
- }
- static void Main()
- {
- Metotlar nesne=new Metotlar();
- int a=nesne.Topla(2,5);
- Console.Write(a);
- }
- }
- static olarak tanımlanan metotlara erişmek için metodun içinde bulunduğu sınıf türünden bir nesne yaratmaya gerek yoktur. static olarak tanımlanan metotlara sadece metodun adını yazarak erişilebilir. Örnek:
- using System;
- class Metotlar {
- static int Topla (int a,int b)
- { return a+b; }
- static void Main()
- {
- int a=Topla(2,5);
- Console.Write(a);
- }
- }
Metot Özellikleri
- 12- Metotlar içinde tanımlanan değişkenler programın başından sonuna kadar durmaz. Bu değişkenler, programın akışı metoda geldiğinde tanımlanır. Metodun işlevi bittiğinde ise bellekten silinirler.
- Programın akışı tekrar metoda geldiğinde değişkenler yeniden tanımlanır ve sonunda yine bellekten silinir. Bu tür değişkenlere otomatik ömürlü nesneler denir.
Metot Parametresi Olarak Diziler
- Diziler C# ‘ta ayrı bir tür olarak ele alındığı için metotlara dizileri aktarmak normal veri türlerinde olduğu gibidir.
- using System;
- class Metotlar1
- {
- static void Yaz(int[] dizi)
- { foreach(int i in dizi)
- Console.WriteLine(i);
- }
- static void Main()
- int[] dizi={1,2,4,7,9}; Yaz(dizi); } }
Dizi ve Değişken Parametreler Arasındaki Fark
- Bu iki programı çalıştırdığınızda göreceksiniz ki metoda parametre olarak aktarılan dizinin metot içinde bir elemanının değiştirilmesi esas diziyi etkiliyor. Ancak metoda parametre olarak aktarılan değişkenin metot içinde değiştirilmesi esas değişkeni etkilemiyor. Çünkü bir metoda parametre olarak bir dizi verildiğinde derleyici metoda dizinin bellekteki adresini verir; metot o adresteki verilerle çalışır. Dolayısıyla da dizinin herhangi bir elemanındaki değişiklik esas diziyi etkileyecektir. Çünkü gerek esas program, gerekse de metot aynı adresteki verilere erişir. Halbuki bir metoda parametre olarak bir değişken verdiğimizde metot için değişkenin bellekteki adresi önemli değildir, metot için önemli olan değişkenin değeridir. Metot, değişkeni kullanabilmek için geçici bir bellek bölgesi yaratır ve parametre olarak aldığı değişkenin değerini bu geçici bellek bölgesine kopyalar ve o geçici bellek bölgesiyle çalışır. Metottan çıkıldığında da o geçici bellek bölgesi silinir.
Değer ve Referans Parametreleri
- Referans türleri metotlara aktarılırken bit bit kopyalanmaz, yani metoda aktarılan sadece bir referanstır. Metot içinde yapılacak değişiklikler nesnenin(dizinin) değerini değiştirebilir.
- C++ dilinde bir nesnenin metoda aktarımı değer ile (call by value) ve referans (call by reference) ile gerçekleştirilir.
- C# dilinde değer tipleri metoda bit bit kopyalanır.
- Değer ve Referans türdeki nesneler metotlara parametre olarak gönderilirken dikkat edilmesi gereken noktalar vardır.
- Değer tipleri parametre olarak verildiğinde fonksiyon içersinde yeni bir nesne oluşturulur ve değeri buraya kopyalanır. Yani fonksiyon içersinde değer tipindeki bir veri değiştiğinde çağıran programdaki ana değer değişmez.
- x değişkeninin değerini metot içinde değiştirmek değerini değiştirmemiştir. Çünkü x değer olarak metoda aktarılmıştır.
- Referans tiplerde ise durum farklıdır. Referans parametre ile metot içinde işlem yapmak nesnenin değerini değiştirebilir.
- Normal koşullarda parametre aktarımlarında değer tipleri ver referans tipler kendi türlerine fonksiyona aktarılırlar. Bazı durumlarda değer tiplerinin metoda referans tip olarak aktarılması istenebilir. Bunun için “ref” ve “out” anahtar sözcükleri kullanılır.
Ref ve Out Anahtar Sözcükleri
- ref anahtar sözcüğü ile belirtilen parametreler değer tipi de olsa referans olarak aktarılırlar. Genellikle değer tiplerini referans olarak metotlara geçirmeye zorlamak için kullanılırlar.
- Referans tipleri metotlara zaten referans olarak aktarıldıkları için ref anahtar sözcüğünü kullanmaya gerek yoktur. Fakat, kullanılması da kısıtlanmamıştır.
Metotların Aşırı Yüklenmesi (Method OverLoading)
- C#’ta parametre sayısı ve/veya parametrelerin türleri farklı olmak şartıyla aynı isimli birden fazla metot tanımlanabilir. Buna metotların aşırı yüklenmesi denir.
- Çalışma zamanında bu metotlar nasıl belirlenecek?
- İsimler aynı olduğuna göre hangi metodu çağırdığımız nasıl anlaşılacak?
- Çalışma zamanında hangi metodun çağrıldığını belirleyebilmek için metodun imzasına (method signature) bakılır.
- Bir metodun imzası metodun adı, parametrelerin sayısı ve türleri ile ilgilidir. Metodun geri dönüş değerleri imzasına dahil değildir.
Değişken Sayıda Parametre Alan Metotlar
- Metotlara gönderilebilecek parametre sayısı bilinmediği zamanlarda değişik sayıda parametre alan metotlar tanımlanabilir.
- Bu metotlar parametreleri dinamik bir dizi içinde depolayarak kullanılmasını sağlarlar.
- Değişken sayıda parametre alan metot tanımlamak için params anahtar sözcüğü kullanılır .
Main Metodu
- Main metodunu diğer metotlardan temel olarak farkı yoktur, tek farkı programın çalışmaya başladığı nokta olmasıdır.
- Main metodunun int türünden bir geri dönüş değeri de olabilir. Bu değer işletim sistemine programın çalışması hakkında bilgi vermek amacıyla kullanılır. Örneğin Main metodu 0 değerini döndürürse işletim sistemi programın düzgün şekilde sonlandırıldığını, 1 değerini döndürürse de hatalı sonlandırıldığını anlayabilecektir.
- Main metodu parametre de alabilir. Komut satırından çalıştırıldığında verilen parametreleri bir string dizisi içinde alarak işleyebilir.
- static int Main (string [] args)
- static int Main (string [] args)Burada komut satırından girilen argümanlar string*+ türündeki args dizisine aktarılıyor. Bu diziyi programımızda gönlümüzce kullanabiliriz. Örneğin programımız deneme.exe olsun. Komut satırından;
- deneme ayşe bekir rabia
- girilirse ilk sözcük olan deneme ile programımız çalıştırılır ve ayşe, bekir ve rabia sözcükleri de string*+ türündeki args dizisine aktarılır. komut satırında program adından sonra girilen ilk sözcük args dizisinin 0. indeksine, ikinci sözcük 1. indeksine, üçüncü sözcük 2. indeksine vs. aktarılır. Örnek bir program:
- using System;
- class Metotlar
- { static void Main(string[] args) {
- Console.WriteLine(“Komut satırından şunları girdiniz: “);
- foreach(string i in args) Console.WriteLine(i); }
- }
Sınıflar(Classes)
- Nesne Yönelimli Programlama(NYP) nedir?
- Çözülmesi istenen problemi çeşitli parçalara ayırıp her bir parça arasındaki ilişkiyi gerçeğine uygun şekilde belirleme tekniğine NYP denir. Nesnelerin kaynak kodundaki karşılığı sınıflardır.
- NYP de her şeyin nesnelere dayalı olması gerekir. C# ‘ta her şey nesne olduğu için %100 nesne yönelimlidir.
- Sınıflar nesne yönelimli programlamanın en önemli ögesidir. Sınıflar sayesinde programlarımızı parçalara bölüp karmaşıklığını azaltırız. Sınıf bildirimleri class anahtar sözcüğü kullanılarak yapılır.
- Sınıfların üye elemanları değişkenler(özellik) ve metotlardı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.
- C# dilinde 5 tane erişim belirleyici vardır.
- public: erişim belirteci ile tanımlanan sınıfın bir özelliğine ya da metoduna istenilen yerden erişime izin verilmiş olur. public üye elemanlar genelde sınıfın dışa sunduğu ara yüzü temsil eder.
- private:erişim belirteci ile tanımlanan üyelere ancak tanımlandıkları sınıfın içindeki diğer üye elemanlar erişebilir, dışarıdan erişmek mümkün değildir.
- protected:erişim belirteci sınıf türemesi yoksa private ile aynıdır. Fakat bir sınıftan başka bir sınıf türetiliyorsa private üyeler diğer sınıfa aktarılmaz, sadece public ve protected elemanlar aktarılırlar.
- internal: internal olarak tanımlanan öğe, bulunduğu assembly’nin (Dll veya Exe dosyası) içinde erişilebilirdir. Dll veya Exe dosyasının içerisinde erişim için kısıtlama yoktur, ama dışarıdan erişilemez. (Her hazırlanan proje farklı assembly dosyası oluşturur)
- protected internal: protected internal erişim belirleyicisi, protected ve internal erişim belirleyicilerinin VEYA (OR) işlemiyle birleştirilmiş halidir. Tanımlandığı class’ın içinde ve o class’tan türetilmiş diğer class’ların içinde erişilebilir. Ayrıca, aynı assembly içinde olmasalar dahi, tanımlandığı class’tan türetilmiş diğer class’ların içinde de erişilebilirdir.
this Anahtar Sözcüğü
- this anahtar sözcüğü ilgili nesnenin referansını belirtir.
- this anahtar sözcüğü, içinde bulunulan nesneye ait bir referans döndürür
- Bunun sayesinde nesnelere ait global alanlara erişme fırsatı bulunur;
Dizililerin metot ve özelliklerde kullanılmas
- Aslında tanımladığımız her dizi Array sınıfı türünden bir nesnedir. İşte bu yüzden tanımladığımız dizilerle Array sınıfının metot ve özelliklerine erişebiliriz.
- Örneğin Length Array sınıfı türünden bir özelliktir ve dizinin eleman sayısını verir. DiziAdi.Length yazılarak bu özelliğe erişilebilir.
- Metot ve özelliklerin geri dönüş tipi bir dizi olabilir.
- Bir dizinin türünü istenilen türe dönüştürmeye yarayan bir sınıf örneği bulunmamaktadır.
- C#’ta diziler arasında bilinçsiz tür dönüşümü mümkün olmadığı gibi, bu işi yapacak metot da yok.
- Aşağıda verilen örnekteki metotlar bu iş için kullanabilirsiniz.
- HATIRLATMA: Metotların parametresindeki dizi, Array DiziAdi yöntemiyle oluşturulduğu için bu dizinin elemanlarına klasik indeksleme yöntemiyle erişemeyiz. Bu yüzden bu dizinin elemanlarına ulaşmak için Array sınıfının GetValue() metodu kullanıldı.
Yapıcı Metotlar(Constructors)
- Bir nesnenin dinamik olarak yaratıldığı anda otomatik olarak çalıştırılan metotlar vardır. Bu metotlar sayesinde bir nesnenin üye elemanlarına ilk değerler verilebilir ya da gerekli ilk düzenlemeler yapılabilir. Bu metotlara yapıcı metotlar (constructors) denir.
- Yapıcı metot tanımlanmasa dahi her sınıfın varsayılan bir yapıcı metodu (default constructor) mutlaka bulunur.
- Daha önceden bahsettiğimiz gibi bir nesne oluşturulduğunda sayısal değerler için 0, referanslar için null, bool türü için false atanır, bu atama bir yapıcı metot ile gerçekleştirilir.
Varsayılan Yapıcı Metot (Default Constructor)
- Genel Özellikleri:
- Yapıcıların dönüş değeri yoktur, isimleri sınıf ile aynı isimdir. Varsayılan yapıcı metodun parametresi yoktur. Nesnenin üye elemanlarına varsayılan değerlerini atar.
- Yapıcı metotlar bir değer tutamaz. Ancak normal metotlardan farklı olarak void anahtar sözcüğü de kullanılmaz.
- Yapıcı metotlar dışarıdan çağrıldığı için genelde public olarak tanımlanırlar. private olursa dışarıdan erişilemez
- Eğer kendi yapıcı metodumuzu tanımlarsak varsayılan yapıcı metotlar çalıştırılmaz.
- Yapıcı metotlar da aşırı yüklenebilir.
- Örneğin public Deneme();, public Deneme(int a);, public Deneme(int a, int b);
Yıkıcı (Destructors) Metotlar
- Nesnelere erişim mümkün olmadığı durumlarda bu nesnelerin heap’ten silinmesi gerekir, çünkü bu nesneler bellek bölgesi işgaline sebep olur. C++’ ta bu işlemi kullanıcı kendi yapmak zorundadır.
- C#’ ta bu işlem için Gereksiz Nesne Toplayıcısı (Garbage Collector) mekanizması mevcuttur. Bu mekanizma gereksiz nesnelerin tuttuğu referans bölgelerini iade eder, ancak bu nesnelerin faaliyet alanlarının ne zaman iade edileceği kesin olarak bilinmez.
- Bu durumda yıkıcı metotlar (destructors) bellek iade işleminden hemen önce çalışarak bu belirsizliğin çözümünde yardımcı olurlar.
- Yıkıcı metotlar bildirilirken sınıf isminin önüne “~” (tilda) işareti eklenir.
- Herhangi bir dönüş değeri ve parametresi yoktur.
- Erişim belirteci (public, private) de kullanılmaz.
- Bir sınıfın sadece bir tane yıkıcı metodu olabilir.
- Örnek programda y nesnesi faaliyet alanını doldurmasına rağmen hemen yok edilmemiştir.
- Bir alt satırda bulunan Console. WriteLine() metodu çalışmış ardından gereksiz nesne toplayıcısı işleyerek nesneyi silmiştir.
- Nesne yok edilirken de yıkıcı metodu çalıştırılmıştır.
- Gereksiz nesne toplayıcı (Garbage Collector) programcının isteği dışında çalışmaktadır.
- System.GC sınıfı kullanılarak istenilen anda bu mekanizma çalıştırılabilir. Fakat bu tavsiye edilen bir kullanım değildir.
Dispose() metodu
- Oluşturulan bir nesnenin kullandığı kaynakların geri alınması için kullanılabilecek yöntemlerden bir diğeri de Dispose() metodudur.
- Türetmiş olduğumuz bir nesnenin hiçbir kaynak tarafından kullanılmadığı ana kadar nesneyi bellekten kaldırmaz tabi bu bazen çok uzun zaman alabilir dolayısı ile bellekte şişmeler olur ve OutOfMemoryException alırız.
- Garbage Collector’a kaynakları boşaltabilmesine yardımcı olmak için Dispose metodu devreye giriyor. Dispose metoduna ulaşmak için yazmış olduğumuz sınıfa IDisposable Interface(Arayüz)sini uygulamamız gerekmektedir.
- IDisposable Interface’si ile Dispose metodu gelir ve bu metod uygulandığı sınıftan türeyen nesnenin işi bittiği anda bellekten kaldırılmasını sağlar.
- Arayüz(Interface) kavramına daha sonra değinilecektir.