C# Operatör Overloading,İndeksleyiciler,Yapılar,Enum Sabitleri,İsim Alanları

C# Operatör Overloading,İndeksleyiciler,Yapılar,Enum Sabitleri,İsim Alanları

Operatör Aşırı Yükleme (Operator OverLoading)

  • Kendi sınıf, metot ve özellikleri yazabildiğimiz gibi operatörlerimizi de yazabiliriz.
  • Nesneye yönelik programlama mantığında yazılan sınıflar için operatörlere yeni anlamlar yüklenebilir. Bu işlem operatör metotları ile gerçekleştirilir.
  • Operatör metotları bir nesnenin ifadeler içinde operatörle kullanıldığında davranışını belirler. Operatör metotları klasik metotlar gibidir.
  • Temel veri türleri için operatörler zaten belirlenmiştir. Dolayısıyla bunlara söz konusu olması mümkün değildir. Fakat kendi tasarladığımız sınıflar için operatörlere yeni anlamlar yüklememiz mümkündür.

 

  • Operatör Metotları Tanımlanırken Uyulması Gereken Kurallar
  • Operatör metotları static olarak tanımlanmalıdır.
  • Operatör metotları isimlerinde “operator” anahtar sözcüğü kullanılmalıdır. (operator+, operator* gibi)
  • Bütün operatör metotları tek ya da iki parametre almalıdır.
  • Klasik metotlar gibi, operatör metotları da aşırı yüklenebilir.
  • Tekli (unary) operatör metotolarında parametre mutlaka sınıf türünden olmalıdır. İkili (binary) operatörlerde ise en az bir parametre ilgili sınıf türünden olmalıdır.
  • Operatör metotlarında ref ve out anahtar sözcükleri kullanılmamalıdır
  • Tanımlama şekli;
  • public static dönüş-tipi operator op (parametre-tipi parametre)
  • Dönüş tipi: Herhangi bir tip olabileceği gibi operatörün aşırı yüklemekte olduğu sınıf ile aynı tipte olabilir. Genellikle tercih edilen sınıf ile aynı tipte olmasıdır.
  • Parametre-tipi : ref ve out anahtar kelimeleri hariç dönüş tipi kullanılabilir. Sınıf tipinde de olabilir.
  • Op: Aşırı yüklenecek operatör (+,/,*,-).
  • Örnek:
  • Karmaşık sayılara ait olmak üzere tanımlanan KarmaşıkSayi sınıfından çeşitli karmaşık sayı nesneleri üretilecektir ve bu nesneler üzerinde aritmetiksel ve mantıksal işlemler yapan çeşitli operatör metotları tanımlanacak ve bunlar aşırı yüklenecektir.

 

Karmaşık Sayı Sınıfının Oluşturulması

 

 

Aritmetiksel Operatörlerin Aşırı Yüklenmesi

  • Dört işlem operatörleri (+, -, *, /) herhangi bir koşul olmaksızın aşırı yüklenebilirler.
  • Tanımlanacak olan operator+ metodu karmaşık sayılar üzerinde toplamı işlemi yaparak ve sonucu yeni bir kompleks sayı nesnesi olarak döndürmektedir

 

 

İlişkisel Operatörlerin Aşırı Yüklenmesi

  •  İlişkisel operatör metotları, true veya false değer ile geri dönerler. İlişkisel operatörler daha önceden de hatırlanacağı gibi 6 tanedir (!= , == , < , > , =)
  •  Bu operatörlerin aşırı yüklenmesinde dikkat edilecek tek husus zıt anlamlı operatörlerin her ikisinin de aynı anda yüklenmiş olması gerektiğidir. Yani operator == bildirilmişse operator != metodu da bildirilmelidir.

 

true ve false Operatörlerin Aşırı Yüklenmesi

  •  Bu iki operatör de aynı anda olmak koşuluyla aşırı yüklenebilirler. Eğer bu operatörler aşırı yüklenirlerse koşul ifadelerini aşağıdaki gibi kullanmak mümkün olur:
  • if (kompleks)
  •  ,……..-
  • else ,……..-

 

Mantıksal Operatörlerin Aşırı Yüklenmesi

  • Mantıksal operatör metotlarının aşırı yüklenmesini 2 kısımda incelemek mümkündür:
  • &,|, ve ! (birinci grup)
  • & ve |, ! operatörlerinin aşırı yüklenebilmesi için herhangi bir şart yoktur.
  • && ve || operatörleri (ikinci grup)
  • && ve || operatörleri direkt olarak aşırı yüklenemezler. Baz ön şartları vardır.
  • & ve | operatörleri aşırı yüklenmiş olmalıdır.
  • true ve false operatörlerinin aşırı yüklenmiş olması gerekir.
  • operator & ve operator | metotlarının parametreleri ilgili sınıfın türünden olmalıdır.
  • operator& ve operator| metotlarının geri dönüş değeri ilgili sınıfın türünden olmalıdır.
  • Yukarıdaki şartlar sağlandığı takdirde bizim ayrıca && ve || operatörlerini aşırı yüklememize gerek kalmaz. Yukarıdaki şartlar sağlandığı takdirde sanki && ve || operatörleri aşırı yüklenmiş olur.

Dönüşüm Operatörlerin Aşırı Yüklenmesi

  • Tür dönüşüm operatörleri ile aşağıdaki bir ifadenin nasıl bir sonuç üretebileceğini bilebiliriz.
  •  KarmasikSayi k = new KarmasikSayi();
  • int a = k;
  • Dönüşüm operatörleri aşırı yüklenmez ise, derleyici yukarıdaki gibi bir durumla karşılaştığında ne yapacağını bilemez.

 

 

Indeksleyiciler (Indexers)

  • Daha önceden de bildiğiniz gibi tanımladığımız diziler System.Array sınıfı türünden bir nesnedir. Bu sayede tanımladığımız diziler üzerinden System.Array sınıfının üye elemanlarına erişebiliriz.
  •  Örneğin System.Array sınıfına ait olan Length özelliği dizimizin kaç elemandan oluştuğunu tutar. Sort() metodu ise dizimizin elemanlarını sıralar.
  • Hatırlarsanız dizilerin elemanlarına *+ operatörüyle erişiyorduk. Yani Array sınıfı türünden bir nesnenin sonuna *+ koyuyorduk ve bunun belirli bir anlamı vardı. Bunu sağlayan System.Array sınıfındaki bir indeksleyeciden başka bir şey değildir. Artık biz de Sinif türünden oluşturduğumuz "a" nesnesini "a[5]" şeklinde yazabileceğiz ve bunun belirli bir anlamı olacak.
  • İndeksleme, dizi elemanlara erişmek için kullanılan “[]” operatöründen gelmektedir.
  • İndeksleyiciler, olsaydı operator [] metodu yerine (böyle bir metot yoktur) faaliyet gösterirlerdi.
  •  İndeksleyiciler genelde sınıfın üye elemanlarından birisi dizi ya da benzer bir türden ise kullanışlı olur. Ancak bu amacın dışında da kullanılması tamamıyla serbesttir.
  • Ancak operatörlerin taşıdıkları anlamlar çerçevesinde kullanılmaları daha doğru olur. İndeksleyiciler tıpkı diziler gibi tek boyutlu indeksleyiciler ve çok boyutlu indeksleyiciler olmak üzere ikiye ayrılır.
  • Indeksleyiciler sahte özelliklere oldukça benziyor. Ancak ciddi farkları da var. Indeksleyici tanımlarken parametre normal parantez yerine köşeli parantezler arasına yazılıyor. Esas programda * ve + arasına girilen veri indeksleyiciye parametre olarak gönderiliyor. İndeksleyicilere özel bir ad verilmiyor, bunun yerine this anahtar sözcüğü kullanılıyor.

 

Tek Boyutlu İndeksleyici

  • Genel Tanımlaması:
  • ElemanTipi this [IndeksTipi indeks
  •  {
  •  get , return değer; -
  •  set , işlemler; …; -
  •  }
  • İndeksleyicilerde indeks değeri dizilerde olduğu gibi tamsayı olmak zorunda değildir.
  •  Fakat ideal kullanımda tamsayı olarak seçilmelidirler.
  •  Örnekte indeks değeri double türündendir ve geri dönen değer rakam*rakam dır. Yani indeksleyicilerin kullanım amacına uygun bir örnek değildir.

Çok Boyutlu indeksleyiciler

  • Çok boyutlu indeksleyicilerin tek boyutlu indeksleyicilerden tek farkı indeksleyicinin aldığı parametre sayısıdır. Örnek:
  • using System;
  • class Sinif
  • { private int Sayi;
  • public int this[int indeks1,int indeks2]
  • { get { return indeks1+indeks2+Sayi; }
  • set { Sayi=indeks1*indeks2+value; } } }
  • class AnaProgram {
  • static void Main() {
  • Sinif a=new Sinif(); a[5,4]=45; Console.WriteLine(a[-6,12]);
  • } }
  • Bu programda a[5,4]=45; satırında 5*4+45 işlemi yapılır ve sonuç Sayi özelliğine atanır. Console.WriteLine(a[-6,12]); satırında ise -6+12+65 işlemi yapılır ve sonuç ekrana yazılır. (sonuç: 71)
  • İndeksleyiciler daha çok sınıfın üye dizilerinden birine direkt erişmek için kullanılırlar.
  • Diziler dinamik olarak oluşturulabilir. Nesne ismine indeks verilerek üye dizinin elemanının değeri elde edilir.
  • İndeksleyiciler de aşırı yüklenebilir. Fakat bu çok kullanılan bir yöntem değildir.
  • NOT: İndeksleyiciler de aşırı yüklenebilir. Bunu ise parametre türünü farklı yaparak sağlarız. NOT: İndeksleyicilerin parametre ve geri dönüş tipi herhangi bir tip olabilir. int olması şart değildir.
  • NOT: İndeksleyicilerin set ve get blokları sahte özelliklerdeki set ve get bloklarının tüm özelliklerini taşırlar. Örneğin set bloğunu koymayarak nesnenin indekslerine değer atanmasını engelleyebiliriz.
  • NOT: Aslında indeksleyicilerin en yaygın kullanımı sınıfımız içindeki bir dizinin elemanlarına direkt nesne ve *+ operatörünü kullanarak erişmektir. Bunu mantığınızı kullanarak yapabilirsiniz.

Yapılar (Structs)

  • C# dilinde yapılar değer tipindedir. Sınıf bildirimine çok benzer şekilde tanımlanırlar. struct anahtar sözcüğü kullanılır
  •  Bazı durumlarda belli bir grup verinin bir arada tanımlanması için sınıfların kullanılması verimsiz olur. Sınıf kullanıldığında stack alanında referans tipte değişken oluşturulur ve üyeler içinde heap alanında ayrıca bellek ayrılır. Verilere ulaşmak için referans kullanmak istenmeyebilir.
  • Bu gibi durumlarda az sayıda ve veri tipindeki değişkenleri yapı şeklinde tanımlamak hız ve verimlilik sağlayabilir.

 

Numaralandırmalar(Enumaration)

 

  • Enum sabitleri sayesinde bazı özel sözcüklerin bazı tam sayıları temsil etmesini sağlayabiliriz. Numaralandırma (enumeration) belli bir sayısal değer alan toplu sabitler tanımlamak için kullanılan bir yapıdır.
  • Tanımlama şekli;
  • enum anahtar sözcüğü ile tanımlanır.
  • enum isim {SOZCUK1,SOZCUK2 };
  • enum isim : tur{ SOZCUK1,SOZCUK2}
  • Burada isim numaralandırmaya verilen tip ismini, parantez içindeki "," ayrılan ifadelerde tanımlayıcıların listesini belirler.
  • enum sabitleri çeşitli sembolleri sayılarla ifade etmek için geliştirilmiş bir veri yapısıdır.
  • enum sabitlerinin varsayılan değeri int türündedir. Fakat diğer tamsayı türleri ile de belirtilebilir. Tanımlanması
  • enum isim,sabit1,sabit2,…- // varsayılan değer tipi int
  •  enum isim : byte ,sabit1,sabit2,…- // tür değeri byte
  • Numaralandırma sabitlere sıfırdan başlayarak artan birer tamsayı değeri verilmesi esasına göre gerçekleştirilir.
  • Enum sabitlerinin türünü byte, sbyte, short, ushort, int, uint, long ve ulong türlerinden biri yapabiliriz.

 

System.Enum sınıfı

  • enum sabitlerine enumAdı.Sabit şeklinde ulaşılır.
  • enum sabitleri de birer veri tipi oldukları için fonksiyona parametre olarak gönderilebilir.
  • System.Enum sınıfından türetildikleri için bazı metotlar ile sabit sembollerin isimleri alınabilir.
  • using System;
  • enum Gunler:byte { PAZARTESI, SALI, CARSAMBA, PERSEMBE, CUMA, CUMARTESI, PAZAR }
  • class Sinif
  • {
  • static void Main()
  •  {
  • string[] a=Gunler.GetNames(typeof(Gunler));
  • Console.WriteLine(a[0]); //veya
  • Console.WriteLine(Gunler.GetNames(typeof(Gunler))[3])
  •  }
  •  }
  •  Bu örnek ekrana alt alta PAZARTESI ve PERSEMBE yazar.

İsim Alanları (NameSpaces)

  • İsim alanları en temel anlamıyla sınıfları organize etmeye (gruplandırmaya) yarayan bir yapıdır.
  • Eski programlama dillerinde, çok kişi tarafından yazılan projelerde, isim çakışmaları meydana gelebilmekteydi. Bu çakışmalar fonksiyon, alt program ya da sınıf isimlerinin değiştirilmesi ile çözülebiliyordu.
  • Bu çözüm sonucunda farklı kişiler ya da firmalar tarafından yazılan aynı isimli metotların firma1Menu(), firma2Menu() vb. şeklinde isimlendirilmesi neden olur.
  • Bu çözüm çok kullanıldıkça fonksiyon isimlerinin önüne anlamsız bir çok ekler gelecektir.
  • Bu karmaşanın önüne geçebilmek için modern dillerde mantıksal bir ayırma yapısı kullanılmaya başlanmıştır.
  • C++ ve C# dillerindeki isim alanları (namespace) ya da Java dilindeki paketler (package) buna birer örnektir.
  • Bu yapılar sayesinde aynı isimde sınıflar, yapılar kolaylıkla tanımlanabilir ve daha önceki tanımlananlarla herhangi bir soruna neden olmaz.
  • Programlara isim alanları using anahtar sözcüğü ile bildirilir.
  • İsim alanlarının bildirilmesi zorunlu olmamakla birlikte sıkıcı tekrarları ortadan kaldırır .
  •  İsim alanı bildirilmediğinde sınıfın, değişkenin ya da metodun tam ismiyle kullanılması gerekmektedir.

 

 

İsim Alanı Bildirimi

  •  İsim alanı namespace anahtar sözcüğü ile bildirilir.
  • Namespace için yine sınıflarda olduğu gibi bir parantez blok açılır. Bu bloğa ise isim alanı içinde yer alacak bildirimler tanımlanır.
  • Örnek bir isim alanı bildirimi
  • namespace IsimAlani
  • {
  • ...
  • }

 

  •  İsim alanları içinde değişken tanımlaması ve ya metot bildirimi yapılamaz.
  • Bir isim alanının içinde yalnızca sınıflar, temsilciler, enum sabitleri, arayüzler ve yapılar direkt olarak bulunabilir. Bundan sonra tüm bunlara kısaca "tür" denir. Temsilciler ve arayüzleri ileride göreceğiz. Örnek bir program:
  •  using System;
  • namespace BirinciIsimAlani
  •  { class Deneme { }
  •  }
  •  class AnaSinif
  •  {
  • static void Main()
  • { BirinciIsimAlani.Deneme d=new BirinciIsimAlani.Deneme(); }
  •  }
  • Gördüğünüz gibi bulunduğumuz isim alanından farklı bir isim alanındaki türle ilgili işlemleri ilgili isim alanını da belirterek yapıyoruz.
  • Farklı konumlarda ya da dosyalarda aynı adlı isim alanları tanımlanabilir. Bu hataya neden olmaz. Çünkü isim alanları mantıksal yapılardır.
  • İsim alanları genellikle kod organizasyonu ve isim çakışmalarını engellemek için kullanılır.
  • Tanımlanan isim alanları using ifadesi ile belirtilebilir.
  • using anahtar sözcüğü tanımlamaların üstünde yer almalıdır. Bu şekilde tanımlandıktan sonra isim alanı içersindeki türlere tam isim belirtmeden erişilebilir.

Henüz Yorum Yapılmamış, İlk Yorumu Siz Yapın

Yorum Yollayın