C# - Operator Overloading (Operatörlerin Aşırı Yüklenmesi)
Normal şartlarda sınıflar üzerinde operatör (- + / vs.) kullanılamaz fakat C# sınıfları operatörlere uygun hale getirmeye imkan veriyor. Sınıfın içine yazacağımız metotlar ile ilgili operatörün nesne için nasıl çalışacağını belirleyebiliyoruz. Bu işleme operatörlerin aşırı yüklenmesi (operator overloading) denir.
Mesela iki boyutlu bir oyun geliştiriyor olalım ve nesnelerin ekrandaki konumunu tutmak için X ve Y değerlerini tutan aşağıdaki sınıfı yazmış olalım.
class Nokta { public int X { get; set; } public int Y { get; set; } }
Çarpışma kontrolü yapmak istedik ve test için aşağıdaki gibi bir şey yazdık.
Nokta a = new Nokta { X = 50, Y = 50 }; Nokta b = new Nokta { X = 50, Y = 50 }; if (a == b) { Console.Write("İki nokta aynı"); } else { Console.Write("İki nokta farklı."); }
Belirlediğimiz her iki nesnede de noktalar (X ve Y değerleri) aynı. Yukarıdaki kontrolü yaptık ve sonucun "aynı" olmasını bekledik ama olmadı. Böyle olmalıydı çünkü şuanda C# bu nesneleri nasıl karşılaştıracağını bilmiyor. Şimdi sınıfın içine iki tane daha metot ekleyip ==
ve !=
operatörlerini aşırı yükleyerek içlerinde X ve Y değerlerini teker teker kontrol edip sonucu döndürelim.
public static bool operator ==(Nokta a, Nokta b) { return (a.X == b.X) && (a.Y == b.Y); } public static bool operator !=(Nokta a, Nokta b) { return (a.X != b.X) || (a.Y != b.Y); }
Operatör aşırı yükleme metotları static olmalıdır ve dönüş tipleri belirlenmelidir. Hangi operatörü aşırı yüklemek istediğimizi yazarız fakat bu metotların isimleri yoktur. İki parametre gelir; birisi nesne1 == nesne2
karşılaştırmasındaki soldaki, diğeri ise sağdaki.
Aynı oyunda iki objenin uzaklığını bulmamız gerektiğini düşünelim. İki sayının farkını almak için mutlak değeri bulunur. Biz de öyle yaparak bir noktanın X ve Y özelliklerinin diğer noktanın özellikleri ile karşılaştırıp mutlak değerini alacağız ve geriye bir Nokta
nesnesi döndüreceğiz. Bu işlem için -
(çıkarma) operatörünü aşırı yükleyeceğiz. Şimdi gerekli metodu yazıp sınıfa ekleyelim.
public static Nokta operator -(Nokta a, Nokta b) { return new Nokta { X = Math.Abs(a.X - b.X), Y = Math.Abs(a.Y - b.Y) }; }
Bu arada bir sayının mutlak değerini almak için Math.Abs
metodu kullanılır. Eşitlik (==) operatörünü aşırı yüklerken geride bool
bir değer döndürmüştük. Ancak - (çıkarma) bir karşılaştırma operatörü olmadığı için nesnenin bir referansını döndürdük. Şimdi aşağıdaki gibi test edip çalışıp çalışmadığına bakalım.
Nokta oyuncu = new Nokta { X = 60, Y = 20 }; Nokta canavar = new Nokta { X = 50, Y = 50 }; Nokta uzaklik = oyuncu - canavar; Console.WriteLine("Yatay uzaklık: " + uzaklik.X); Console.WriteLine("Dikey uzaklık: " + uzaklik.Y);
Aşağıdaki çıktıyı almış olmalısınız.
Bu arada aşırı yüklenen metodun ikinci parametresi bir nesne olmak zorunda değil. İsterseniz int, string, float gibi built-in tipler ile de karşılaştırma yapabilirsiniz. Tabi ona göre metot yazmalısınız.