Merhaba, C# derslerimize yine sınıflar ile devam ediyoruz. Bu makalemizde sınıfların son bölümünü anlatacağız. Bu bölümde static sınıflar, singleton sınıflar, struct ve enum yapılarından bahsedeceğiz. Bir önceki dersimizde this, get ve set anahtar kelimeleri ile, constructor ve destructor metotlarından bahsetmiştik.
DERS 12 : Sınıflar 3
Static sınıflar, metotlar ve değişkenler
Static sınıfları anlatmadan önce static metotlardan bahsetmek gerekiyor. Bir sınıfın içerisinde yer alan static bir metotu, o sınıftan herhangi bir nesne tanımlamadan çağırabiliriz. Static bir metodun içerisinde, sınıfa ait static olmayan bir değişken kullanamayız. Static metodları sınıftan bağımsız metotlar olarak düşünebilirsiniz. Herhangi bir metodu veya değişkeni static olarak tanımlamak için erişim belirleyiciden sonra static anahtar kelimesini yazmanız yeterli.
class Program
{
static void Main(string[] args)
{
int area = Rectangle.CalculateArea(5, 10);
Rectangle rectangle = new Rectangle();
}
}
public class Rectangle
{
public int Width { get; set; }
public int Height { get; set; }
public static int CalculateArea(int width, int height)
{
return width * height;
}
}
Yukarıdaki kod bloğunda CalculateArea metodu bir static metottur. Gördüğünüz gibi metodu çağırırken Rectangle.CalculateArea şeklinde çağırdık. Yani Rectangle sınıfından yeni bir nesne türetmedik. Eğer oluşturduğumuz rectangle nesnesini kullanarak bu metodu çağırmaya çalışsaydık (rectangle.CalculateArea şeklinde) aşağıdaki gibi bir hata alacaktık ve projemiz build olmayacaktı:
Member ‘Rectangle.CalculateArea(int, int)’ cannot be accessed with an instance reference; qualify it with a type name instead
Bir sınıf içerisine hem static hem de static olmayan metotlar yazabilirsiniz. Bir sınıfınız olsun ve bu sınıf içerisinde sadece static metotlar bulunsun istiyorsanız, işte o zaman devreye static sınıflar giriyor. Yapmanız gereken tek şey, metot tanımında olduğu gibi class tanımının başına static anahtar kelimesini eklemek. Static sınıf içerisindeki tüm field, property ve metotlar static olmak zorundadır. Static olarak tanımladığınız bir sınıftan nesne türetemezsiniz, yani new Rectangle() şeklinde bir komut kullanamazsınız. Tüm çağrımları Rectangle.MetotIsmi şeklinde yapmalısınız.
class Program
{
static void Main(string[] args)
{
Rectangle.Width = 5;
Rectangle.Height = 10;
int area = Rectangle.CalculateArea();
}
}
public static class Rectangle
{
public static int Width { get; set; }
public static int Height { get; set; }
public static int CalculateArea()
{
return Width * Height;
}
}
Yukarıdaki kod bloğunda Rectangle sınıfımızı ve içerisindeki tüm elemanları static olarak işaretledik. Main metodunda bu static elemanları nasıl kullandığımızı görebilirsiniz. Static olmayan bir sınıf içerisinde static değişkenler kullanırken çok dikkatli olmalısınız. Çünkü bir static değişken tüm uygulama boyunca bir kez oluşturulur. Dolayısıyla eğer bir web uygulaması yapıyorsanız ve static değişkenler kullanmışsanız, sitenize bir A kişisi girdiğinde, onun setlemiş olduğu bir değeri alakasız bir B kişisinin görme ihtimali vardır. Bir örnekle anlatmaya çalışayım.
class Program
{
static void Main(string[] args)
{
Account account1 = new Account();
int number1 = account1.GetAccountNumber();
Account account2 = new Account();
int number2 = account2.GetAccountNumber();
}
}
public class Account
{
private static int AccountNumber;
public int GetAccountNumber()
{
if (AccountNumber == 0)
{
AccountNumber = new Random().Next();
}
return AccountNumber;
}
}
Yukarıdaki örnekte iki adet Account nesnesi oluşturuyoruz. Account sınıfı içerisindeki AccountNumber alanı static olarak işaretlenmiş. Bu demek oluyor ki program boyunca sadece bir adet AccountNumber değişkeni olacak. Dolayısıyla bizim oluşturmuş olduğumuz iki farklı Account nesnesi (account1 ve account2) aynı AccountNumber değişkenini kullanacak. Bu yüzden de number1 ve number2 değişkenleri birbirine eşit olacaktır. Bu gibi sebeplerden dolayı static kullanırken dikkatli olmak gerekiyor.
Singleton sınıflar
Singleton, kelime anlamı olarak tek demek. Singleton sınıf ise, program boyunca bu sınıf tipindeki bir nesneden sadece bir tane olacağını garantiler. Yani siz Rectangle sınıfını singleton yaparsanız, tüm program boyunca sadece bir tane Rectangle tipinde değişkeniniz olabilir demektir. Peki bu ne zaman faydalı olabilir, nerde kullanılabilir? Örneğin veritabanı bağlantı objesi tüm program boyunca tek olabilir. Her yeni sorguda yeni bir obje oluşturup, tekrar tekrar veritabanına bağlantı açmak performans açısından pek sağlıklı olmayacaktır. Bu durumda singleton sınıflar kullanılabilir. Rectangle sınıfımızı singleton yapmak için aşağıdaki gibi bir kod yazmamız yeterli.
class Program
{
static void Main(string[] args)
{
Rectangle singleton = Rectangle.Instance;
}
}
public class Rectangle
{
private static Rectangle rectangle = new Rectangle();
public static Rectangle Instance
{
get
{
return rectangle;
}
}
}
Gördüğünüz gibi aslında çok da karışık değil. Rectangle tipinde private static bir değişken tanımlıyoruz ve Rectangle.Instance dediğimiz her durumda bu değişkeni dönüyoruz. Dolayısıyla tüm program boyunca sadece bir adet Rectangle değişkenimiz oluyor.
struct
Sınıf tanımlarının nasıl yapıldığını gördük. Sınıflar, referans tipli değişkenlerdir. Sınıfla benzer yapıları kullanmak ve referans değil de değer tipli değişken olarak kullanılan bir yapı arıyorsanız, bunun adı struct‘tır. Rectangle sınıfından bir nesne oluşturduğunuzda bu nesneye referans yolu ile erişirsiniz; ancak eğer bu sınıfın içerisindeki değişken sayısı az ise referans yolu ile kullanım bellek kaybına yol açacaktır. Bu durumda class yerine struct kullanmak daha mantıklı olacaktır. struct tanımları class tanımları ile neredeyse aynıdır. class anahtar sözcüğü yerine struct kullanmanız yeterlidir. struct yapısından çok fazla bahsetmeyeceğim, şahsen ben pek kullanma ihtiyacı hissetmedim. struct ile ilgili detaylı bilgiye Google üzerinden erişebilirsiniz.
enum
enum kelimesi enumeration’ın kısaltmasıdır ve numaralandırma anlamına gelir. Örneğin bir oyun yazıyorsunuz ve oyunda yön bilgisine ihtiyacınız var. Bu bilgiyi farklı şekillerde tutabilirsiniz. Örneğin, yukarı=0, sağa=1, aşağı=2, sola=3 şeklinde bir değişken ataması yapabilirsiniz veya bu atamayı kafanızda yapıp kod tarafında 0,1,2,3 kullanabilirsiniz. Daha mantıklı bir yaklaşım olarak da enum kullanabilirsiniz.
class Program
{
static void Main(string[] args)
{
Direction direction = Direction.Up;
if (direction == Direction.Up)
{
}
else if ((int)direction == 2)
{
}
else if (direction.ToString() == "Left")
{
}
}
}
public enum Direction
{
Up = 0,
Right = 1,
Down = 2,
Left = 3
}
Yukarıdaki örnekte Direction isminde bir enum tanımladık. Programımızda ise bu enum tanımını üç farklı şekilde kullandık: enum olarak, int olarak ve string olarak. enum tanımlarını yaparken, sağ taraftaki sayıları vermek zorunda değilsiniz. Bu sayıları vermediğinizde 0’dan başlayacak şekilde otomatik olarak atanacaktır. Eğer isterseniz de tamamen rastgele atamalar da yapabilirsiniz, yani ardışık olması gerekmiyor. enum tipi çok kullanışlıdır. Günlük hayatta karşınıza bolca çıkacaktır.
Böylelikle bir dersimizin daha sonuna gelmiş olduk. Bu dersimizle birlikte sınıfları bitirdik. Bir sonraki dersimizde dosya işlemlerini anlatacağız. Dosya işlemlerinden sonra, Nesne Yönelimli Programlama konu başlığı altında, tekrar sınıflara değineceğiz. Görüşmek üzere…