C# ve .NET [4]
Giriş: Neden Nesne Yönelimli Programlama ve Sınıflar? Prosedürel programlama gibi eski yaklaşımlarda, programlar genellikle bir dizi fonksiyon veya prosedür etrafında organize edilirdi ve veriler genellikle bu fonksiyonlardan ayrı olarak yönetilirdi. Uygulamalar büyüdükçe, bu yaklaşım veri ve fonksiyonlar arasındaki ilişkileri takip etmeyi zorlaştırabilir, kod tekrarına yol açabilir ve değişiklik yapmayı riskli hale getirebilirdi. Nesne Yönelimli Programlama (OOP), bu sorunlara bir çözüm olarak ortaya çıktı. OOP’nin temel fikri, ilgili verileri (data/attributes) ve bu veriler üzerinde çalışan işlevleri (behaviors/methods) mantıksal birimler halinde nesneler (objects) içinde birleştirmektir. Bu birleştirmeye kapsülleme (encapsulation) denir. Sınıflar (Classes) ise bu nesnelerin nasıl oluşturulacağını tanımlayan şablonlar, kalıplar veya planlardır (blueprints). Bir sınıf, belirli bir türdeki nesnelerin sahip olacağı ortak özellikleri (alanlar ve özellikler aracılığıyla saklanan veri) ve gerçekleştirebileceği eylemleri (metotlar aracılığıyla tanımlanan davranış) tanımlar. Örneğin, bir “Araba” sınıfı tanımlayabiliriz. Bu sınıf, tüm arabaların ortak özelliklerini (renk, marka, model, hız) ve davranışlarını (hızlan, yavaşla, korna çal) belirtir. Daha sonra bu “Araba” sınıfından belirli araba nesneleri (örnekler — instances) oluşturabiliriz: kırmızı bir Ferrari, mavi bir Ford, beyaz bir Toyota. Her bir araba nesnesi, “Araba” sınıfının planına uyar ancak kendi özel veri değerlerine (kendi rengi, kendi hızı vb.) sahip olur. OOP ve sınıflar bize şu avantajları sağlar: Modülerlik: Kod, mantıksal nesnelere ayrılır. Yeniden Kullanılabilirlik: Sınıflar ve içindeki metotlar farklı yerlerde tekrar kullanılabilir. Kalıtım ile mevcut sınıflar genişletilebilir. Bakım Kolaylığı: Bir nesnenin iç mantığını değiştirmek, genellikle sistemin diğer kısımlarını daha az etkiler. Hataları bulmak ve düzeltmek kolaylaşır. Anlaşılabilirlik: Gerçek dünya kavramlarını kodda modellemek, programın anlaşılmasını kolaylaştırır. Esneklik: Çok biçimlilik (polymorphism) gibi mekanizmalar sayesinde kod daha esnek ve genişletilebilir hale gelir. Bölüm 1: C#’ta Sınıf (Class) Tanımlama C#’ta bir sınıf tanımlamak için class anahtar kelimesi kullanılır, ardından sınıfa bir isim verilir ve sınıfın üyeleri kıvırcık parantezler {} içine yazılır. Temel Sözdizimi: [erişim_belirleyici] class SinifAdi { // Sınıf Üyeleri: // 1. Alanlar (Fields) - Veri depolama (genellikle private) // 2. Özellikler (Properties) - Alanlara kontrollü erişim (get/set) // 3. Metotlar (Methods) - Davranışlar, eylemler // 4. Yapıcılar (Constructors) - Nesne oluşturma ve başlatma // 5. Yıkıcılar (Destructors/Finalizers) - Nesne yok edilmeden önce temizlik (nadiren kullanılır) // 6. Olaylar (Events) - Durum değişikliklerini bildirme // 7. İndeksleyiciler (Indexers) - Nesneye dizi gibi erişim // 8. Operatör Aşırı Yüklemesi (Operator Overloading) // 9. İç İçe Türler (Nested Types) } erişim_belirleyici: Sınıfın başka kod parçalarından ne kadar erişilebilir olduğunu belirler. En yaygın olanları: public: Her yerden erişilebilir. internal (Varsayılan, eğer belirtilmezse): Sadece aynı derleme (assembly) içinden erişilebilir. Diğerleri: protected, private, protected internal, private protected (Kalıtım ve iç içe sınıflarla ilgilidir). class: Sınıf tanımını başlatan anahtar kelime. SinifAdi: Sınıfa verilen isim (PascalCase adlandırma kuralı önerilir). { … }: Sınıfın gövdesi. Sınıf üyeleri buraya tanımlanır. Örnek Basit Sınıf: using System; namespace SinifNesneTemelleri { public class Ogrenci // Her yerden erişilebilir Ogrenci sınıfı { // Alanlar (Fields) - Genellikle private yapılır private string _ad; private int _yas; private string _bolum; private bool _aktif; // Yapıcı (Constructor) - Nesne oluşturulduğunda çalışır public Ogrenci(string ad, int yas, string bolum) { Console.WriteLine("Ogrenci nesnesi oluşturuluyor..."); _ad = ad; _yas = yas; _bolum = bolum; _aktif = true; // Varsayılan değer } // Özellik (Property) - Alanlara kontrollü erişim sağlar public string Ad { get { return _ad; } // Okuma erişimi // set { _ad = value; } // Yazma erişimi (istersek kısıtlayabiliriz) } public int Yas { get { return _yas; } set { // Değer kontrolü eklenebilir if (value > 0 && value < 150) { _yas = value; } else { Console.WriteLine("Geçersiz yaş değeri!"); } } } // Otomatik Uygulanan Özellik (Auto-Implemented Property - Daha kısa) // Derleyici arka planda private bir alan oluşturur. public string Bolum { get; set; } // He
![C# ve .NET [4]](https://media2.dev.to/dynamic/image/width%3D1000,height%3D500,fit%3Dcover,gravity%3Dauto,format%3Dauto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2l2a6ah56piev21yvuxl.png)
Giriş: Neden Nesne Yönelimli Programlama ve Sınıflar?
Prosedürel programlama gibi eski yaklaşımlarda, programlar genellikle bir dizi fonksiyon veya prosedür etrafında organize edilirdi ve veriler genellikle bu fonksiyonlardan ayrı olarak yönetilirdi. Uygulamalar büyüdükçe, bu yaklaşım veri ve fonksiyonlar arasındaki ilişkileri takip etmeyi zorlaştırabilir, kod tekrarına yol açabilir ve değişiklik yapmayı riskli hale getirebilirdi.
Nesne Yönelimli Programlama (OOP), bu sorunlara bir çözüm olarak ortaya çıktı. OOP’nin temel fikri, ilgili verileri (data/attributes) ve bu veriler üzerinde çalışan işlevleri (behaviors/methods) mantıksal birimler halinde nesneler (objects) içinde birleştirmektir. Bu birleştirmeye kapsülleme (encapsulation) denir.
Sınıflar (Classes) ise bu nesnelerin nasıl oluşturulacağını tanımlayan şablonlar, kalıplar veya planlardır (blueprints). Bir sınıf, belirli bir türdeki nesnelerin sahip olacağı ortak özellikleri (alanlar ve özellikler aracılığıyla saklanan veri) ve gerçekleştirebileceği eylemleri (metotlar aracılığıyla tanımlanan davranış) tanımlar.
Örneğin, bir “Araba” sınıfı tanımlayabiliriz. Bu sınıf, tüm arabaların ortak özelliklerini (renk, marka, model, hız) ve davranışlarını (hızlan, yavaşla, korna çal) belirtir. Daha sonra bu “Araba” sınıfından belirli araba nesneleri (örnekler — instances) oluşturabiliriz: kırmızı bir Ferrari, mavi bir Ford, beyaz bir Toyota. Her bir araba nesnesi, “Araba” sınıfının planına uyar ancak kendi özel veri değerlerine (kendi rengi, kendi hızı vb.) sahip olur.
OOP ve sınıflar bize şu avantajları sağlar:
Modülerlik: Kod, mantıksal nesnelere ayrılır.
Yeniden Kullanılabilirlik: Sınıflar ve içindeki metotlar farklı yerlerde tekrar kullanılabilir. Kalıtım ile mevcut sınıflar genişletilebilir.
Bakım Kolaylığı: Bir nesnenin iç mantığını değiştirmek, genellikle sistemin diğer kısımlarını daha az etkiler. Hataları bulmak ve düzeltmek kolaylaşır.
Anlaşılabilirlik: Gerçek dünya kavramlarını kodda modellemek, programın anlaşılmasını kolaylaştırır.
Esneklik: Çok biçimlilik (polymorphism) gibi mekanizmalar sayesinde kod daha esnek ve genişletilebilir hale gelir.
Bölüm 1: C#’ta Sınıf (Class) Tanımlama
C#’ta bir sınıf tanımlamak için class anahtar kelimesi kullanılır, ardından sınıfa bir isim verilir ve sınıfın üyeleri kıvırcık parantezler {} içine yazılır.
Temel Sözdizimi:
[erişim_belirleyici] class SinifAdi
{
// Sınıf Üyeleri:
// 1. Alanlar (Fields) - Veri depolama (genellikle private)
// 2. Özellikler (Properties) - Alanlara kontrollü erişim (get/set)
// 3. Metotlar (Methods) - Davranışlar, eylemler
// 4. Yapıcılar (Constructors) - Nesne oluşturma ve başlatma
// 5. Yıkıcılar (Destructors/Finalizers) - Nesne yok edilmeden önce temizlik (nadiren kullanılır)
// 6. Olaylar (Events) - Durum değişikliklerini bildirme
// 7. İndeksleyiciler (Indexers) - Nesneye dizi gibi erişim
// 8. Operatör Aşırı Yüklemesi (Operator Overloading)
// 9. İç İçe Türler (Nested Types)
}
erişim_belirleyici: Sınıfın başka kod parçalarından ne kadar erişilebilir olduğunu belirler. En yaygın olanları:
public: Her yerden erişilebilir.
internal (Varsayılan, eğer belirtilmezse): Sadece aynı derleme (assembly) içinden erişilebilir.
Diğerleri: protected, private, protected internal, private protected (Kalıtım ve iç içe sınıflarla ilgilidir).
class: Sınıf tanımını başlatan anahtar kelime.
SinifAdi: Sınıfa verilen isim (PascalCase adlandırma kuralı önerilir).
{ … }: Sınıfın gövdesi. Sınıf üyeleri buraya tanımlanır.
Örnek Basit Sınıf:
using System;
namespace SinifNesneTemelleri
{
public class Ogrenci // Her yerden erişilebilir Ogrenci sınıfı
{
// Alanlar (Fields) - Genellikle private yapılır
private string _ad;
private int _yas;
private string _bolum;
private bool _aktif;
// Yapıcı (Constructor) - Nesne oluşturulduğunda çalışır
public Ogrenci(string ad, int yas, string bolum)
{
Console.WriteLine("Ogrenci nesnesi oluşturuluyor...");
_ad = ad;
_yas = yas;
_bolum = bolum;
_aktif = true; // Varsayılan değer
}
// Özellik (Property) - Alanlara kontrollü erişim sağlar
public string Ad
{
get { return _ad; } // Okuma erişimi
// set { _ad = value; } // Yazma erişimi (istersek kısıtlayabiliriz)
}
public int Yas
{
get { return _yas; }
set
{
// Değer kontrolü eklenebilir
if (value > 0 && value < 150)
{
_yas = value;
}
else
{
Console.WriteLine("Geçersiz yaş değeri!");
}
}
}
// Otomatik Uygulanan Özellik (Auto-Implemented Property - Daha kısa)
// Derleyici arka planda private bir alan oluşturur.
public string Bolum { get; set; } // Hem get hem set public
public bool AktifMi
{
get { return _aktif; }
// Set bloğu yoksa, bu özellik salt okunur (read-only) olur (yapıcıda ayarlanabilir)
}
// Metot (Method) - Nesnenin davranışı
public void BilgiYazdir()
{
string durum = _aktif ? "Aktif" : "Pasif";
Console.WriteLine($"Ad: {Ad}, Yaş: {Yas}, Bölüm: {Bolum ?? _bolum}, Durum: {durum}");
// Not: Bolum özelliği get/set olduğu için doğrudan this.Bolum da kullanılabilir.
// _bolum alanına doğrudan erişim de mümkündür (aynı sınıf içinde olduğumuz için).
}
public void MezunEt()
{
if (_aktif)
{
_aktif = false;
Console.WriteLine($"{Ad} mezun edildi.");
} else {
Console.WriteLine($"{Ad} zaten mezun veya pasif.");
}
}
}
}
Bölüm 2: Nesne (Object) Oluşturma (Instantiation)
Bir sınıftan nesne (object) veya örnek (instance) oluşturma işlemine örnekleme (instantiation) denir. Bu işlem new anahtar kelimesi ve sınıfın yapıcı metodu (constructor) kullanılarak yapılır.
Sözdizimi:
SinifAdi degiskenAdi = new SinifAdi(yapici_argümanları);
Örnek:
using SinifNesneTemelleri; // Eğer farklı bir namespace'deyse using gerekir
public class Uygulama
{
public static void Main(string[] args)
{
// Ogrenci sınıfından nesneler oluşturma
Ogrenci ogr1 = new Ogrenci("Ali Veli", 20, "Bilgisayar Mühendisliği");
Ogrenci ogr2 = new Ogrenci("Ayşe Kara", 22, "Elektrik Mühendisliği");
// Ogrenci ogr3 = new Ogrenci(); // Hata! Uygun parametre alan bir yapıcı metot tanımlı.
// Nesnelerin özelliklerine erişme ve metotlarını çağırma
Console.WriteLine($"Öğrenci 1 Adı: {ogr1.Ad}"); // Özellik (get)
ogr2.Yas = 23; // Özellik (set)
// ogr1.Ad = "Can"; // Hata! Ad özelliğinin set bloğu yok (veya private).
ogr1.Bolum = "Yazılım Müh."; // Otomatik özellik (set)
Console.WriteLine($"Öğrenci 2 Bölümü: {ogr2.Bolum}"); // Otomatik özellik (get)
Console.WriteLine($"Öğrenci 1 Aktif mi? {ogr1.AktifMi}");
Console.WriteLine("\nBilgiler:");
ogr1.BilgiYazdir(); // Metot çağırma
ogr2.BilgiYazdir();
Console.WriteLine("\nMezuniyet:");
ogr1.MezunEt();
ogr1.MezunEt(); // Tekrar mezun etmeye çalışma
ogr1.BilgiYazdir();
}
}
new Ogrenci(…) ifadesi şunları yapar:
Heap bellekte yeni bir Ogrenci nesnesi için yer ayırır.
Belirtilen argümanlarla eşleşen Ogrenci sınıfındaki yapıcı metodu (Ogrenci(string ad, int yas, string bolum)) çağırır.
Yapıcı metot içindeki kod çalışır (this yeni oluşturulan nesneyi gösterir) ve nesnenin başlangıç durumu ayarlanır.
Heap’teki yeni nesnenin bellek adresi (referansı) ogr1 (veya ogr2) değişkenine atanır. ogr1 ve ogr2 artık farklı Ogrenci nesnelerine referans tutar.
Bölüm 3: Sınıf Üyeleri (Class Members)
Sınıflar, verileri ve davranışları temsil eden çeşitli üyeler içerir.
3.1. Alanlar (Fields)
Sınıfın içinde doğrudan tanımlanan değişkenlerdir.
Nesnenin durumunu (verisini) depolamak için kullanılırlar.
Genellikle private erişim belirleyicisi ile tanımlanırlar. Bu, alanlara sınıf dışından doğrudan erişimi engeller ve kapsülleme (encapsulation) prensibini destekler. Veriye erişim ve değişiklik, kontrollü bir şekilde özellikler (properties) aracılığıyla sağlanır.
Adlandırma Kuralı: Genellikle _ (alt çizgi) ile başlar ve camelCase kullanılır (örn. _kullaniciAdi, _mevcutHiz).
public class BankaHesabi
{
private string _hesapSahibi; // Private alan
private decimal _bakiye; // Private alan
// ...
}
3.2. Özellikler (Properties)
Alanlara (fields) kontrollü erişim sağlayan özel metot benzeri üyelerdir. Dışarıdan bakıldığında alan gibi görünürler ancak aslında arka planda metotlar çalıştırırlar.
Kapsüllemeyi sağlamanın standart yoludur.
Bir özelliğin get erişimcisi (accessor) değeri okumak için, set erişimcisi ise değeri yazmak (atama yapmak) için kullanılır.
Erişimciler public, private, protected gibi farklı erişim belirleyicilere sahip olabilir.
get veya set bloklarından biri veya her ikisi de tanımlanabilir. Sadece get varsa özellik salt okunur (read-only), sadece set varsa (nadiren kullanılır) salt yazılır (write-only) olur.
set bloğu içinde, atanmaya çalışılan değere value anahtar kelimesi ile erişilir. Burada doğrulama (validation) veya başka mantıklar eklenebilir.
public class BankaHesabi
{
private string _hesapSahibi;
private decimal _bakiye;
private readonly string _hesapNumarasi; // Sadece yapıcıda atanabilen salt okunur alan
// HesapSahibi özelliği (sadece okunabilir)
public string HesapSahibi
{
get { return _hesapSahibi; }
// Set bloğu yok
}
// Bakiye özelliği (okunabilir, kontrollü yazılabilir)
public decimal Bakiye
{
get { return _bakiye; }
private set // Sadece sınıf içinden bakiye değiştirilebilir (örn. ParaYatir metoduyla)
{
if (value >= 0) // Negatif bakiye olamaz
{
_bakiye = value;
}
// else { throw new ArgumentOutOfRangeException(...); } // Hata fırlatılabilir
}
}
// HesapNumarası özelliği (salt okunur)
public string HesapNumarasi => _hesapNumarasi; // C# 6+ Expression-bodied property (get için kısa yol)
public BankaHesabi(string sahip, string hesapNo, decimal ilkBakiye = 0)
{
_hesapSahibi = sahip;
_hesapNumarasi = hesapNo; // readonly alan yapıcıda atanabilir
if (ilkBakiye >= 0)
{
// Bakiye özelliğinin set erişimcisi private olsa da,
// sınıf içinden erişilebilir. Bu, validasyonun çalışmasını sağlar.
this.Bakiye = ilkBakiye;
}
}
// Para yatırma metodu (Bakiye'yi dolaylı yoldan değiştirir)
public void ParaYatir(decimal miktar) {
if (miktar > 0) {
this.Bakiye += miktar; // private set'e sınıf içinden erişim
}
}
// ... ParaCek metodu vb. ...
}
Otomatik Uygulanan Özellikler (Auto-Implemented Properties):
Eğer get ve set blokları içinde özel bir mantık yoksa (sadece değeri alıp ayarlıyorsa), C# daha kısa bir söz dizimi sunar. Derleyici arka planda otomatik olarak private bir alan oluşturur.
public class Urun
{
// Otomatik özellikler
public int Id { get; set; }
public string Ad { get; set; }
public decimal Fiyat { get; private set; } // Fiyat dışarıdan okunabilir ama sadece içeriden ayarlanabilir
public int Stok { get; init; } // C# 9+ init erişimcisi: Sadece nesne başlatıcıda veya yapıcıda atanabilir (immutable'a yakın)
public Urun(int id, decimal fiyat)
{
this.Id = id;
this.Fiyat = fiyat; // private set'e yapıcıdan erişilebilir
}
}
// Kullanım
Urun u = new Urun(1, 100m) { Ad = "Kalem", Stok = 50 }; // init özelliği nesne başlatıcıda atanabilir
// u.Fiyat = 110m; // Hata! Set private.
// u.Stok = 40; // Hata! init sadece başlangıçta atanabilir.
3.3. Metotlar (Methods)
Nesnenin gerçekleştirebileceği eylemleri veya davranışları tanımlayan fonksiyonlardır.
Sınıfın özelliklerini (alanlarını) okuyabilir ve değiştirebilirler (this anahtar kelimesi ile).
Parametre alabilir ve bir değer döndürebilirler (void ise değer döndürmez).
Erişim belirleyicileri (public, private vb.) alırlar.
public class Daire
{
public double Yaricap { get; set; }
public Daire(double yaricap)
{
Yaricap = yaricap;
}
// Alan hesaplayan metot
public double AlanHesapla()
{
return Math.PI * Yaricap * Yaricap;
}
// Çevre hesaplayan metot
public double CevreHesapla()
{
return 2 * Math.PI * Yaricap;
}
// Özel (private) yardımcı metot
private bool YaricapGecerliMi()
{
return Yaricap > 0;
}
public void Bilgi()
{
if(YaricapGecerliMi()) // Özel metodu çağır
{
Console.WriteLine($"Yarıçap: {Yaricap}, Alan: {AlanHesapla():F2}, Çevre: {CevreHesapla():F2}");
} else {
Console.WriteLine("Geçersiz daire!");
}
}
}
3.4. Yapıcılar (Constructors)
Bir sınıftan new anahtar kelimesiyle yeni bir nesne oluşturulduğunda otomatik olarak çağrılan özel metotlardır.
Temel amaçları, nesnenin başlangıç durumunu ayarlamak ve gerekli başlangıç değerlerini atamaktır.
Sınıfla aynı isme sahiptirler.
Geri dönüş türleri yoktur ( void bile yazılmaz).
Erişim belirleyicileri olabilir (public en yaygın olanıdır).
Parametre alabilirler (nesne oluşturulurken argümanlar bu parametrelere geçer).
Aşırı Yüklenebilirler (Overloading): Bir sınıfın farklı parametre listelerine sahip birden fazla yapıcısı olabilir. Hangi yapıcının çağrılacağı, new ile birlikte verilen argümanlara göre belirlenir.
Varsayılan Yapıcı (Default Constructor): Eğer siz hiçbir yapıcı tanımlamazsanız, derleyici otomatik olarak parametresiz, public bir varsayılan yapıcı oluşturur (tüm alanları varsayılan değerlerine ayarlar). Ancak, siz en az bir tane yapıcı tanımlarsanız, derleyici artık varsayılan yapıcıyı oluşturmaz. Parametresiz bir yapıcıya ihtiyacınız varsa onu açıkça tanımlamanız gerekir.
this(…) Kullanımı: Bir yapıcı, aynı sınıf içindeki başka bir yapıcıyı çağırmak için this(…) söz dizimini kullanabilir (yapıcı zincirleme).
public class Kitap
{
public string Baslik { get; set; }
public string Yazar { get; set; }
public int SayfaSayisi { get; set; }
// Parametresiz yapıcı (varsayılan değerlerle)
public Kitap() : this("Bilinmiyor", "Bilinmiyor", 0) // Diğer yapıcıyı çağırır
{
Console.WriteLine("Parametresiz Kitap yapıcısı çağrıldı.");
// Artık derleyici varsayılan boş yapıcıyı oluşturmaz.
}
// İki parametreli yapıcı
public Kitap(string baslik, string yazar) : this(baslik, yazar, -1) // Üç parametreliyi çağırır
{
Console.WriteLine("İki parametreli Kitap yapıcısı çağrıldı.");
}
// Üç parametreli ana yapıcı
public Kitap(string baslik, string yazar, int sayfaSayisi)
{
Console.WriteLine("Üç parametreli Kitap yapıcısı çağrıldı.");
Baslik = baslik;
Yazar = yazar;
SayfaSayisi = sayfaSayisi > 0 ? sayfaSayisi : 0; // Basit validasyon
}
}
// Kullanım
Kitap k1 = new Kitap(); // Parametresiz -> Diğerlerini zincirler
Kitap k2 = new Kitap("Suç ve Ceza", "Dostoyevski"); // İki parametreli -> Üç parametreliyi zincirler
Kitap k3 = new Kitap("Sefiller", "Victor Hugo", 1400); // Üç parametreli
3.5. this Anahtar Kelimesi
Sınıfın örnek (instance) üyeleri (alanlar, özellikler, metotlar) içinde, o an üzerinde işlem yapılan nesne örneğinin kendisine referans vermek için kullanılır.
Alan/Özellik Erişimi: Özellikle metot parametreleri ile sınıf alanları/özellikleri aynı isme sahip olduğunda, sınıf üyesine erişmek için kullanılır (this.alanAdi = parametreAdi;).
Yapıcı Zincirleme: this(…) şeklinde başka bir yapıcıyı çağırmak için.
Metot Çağırma: Aynı nesnenin başka bir metodunu çağırmak için (this.BaskaMetot();).
İndeksleyici (Indexer) İçinde: İndeksleyiciye erişilen nesneyi temsil eder.
Uzantı Metotları (Extension Methods) İçinde: Uzantı metodunun çağrıldığı nesne örneğini temsil eder (ilk parametre olarak).
Bölüm 4: Statik Üyeler (static)
Normal sınıf üyeleri (alanlar, özellikler, metotlar), sınıftan oluşturulan her bir nesne örneğine aittir. Her nesnenin kendi _ad, _yas alanı vardır. Ancak bazen, belirli bir nesne örneğine değil, doğrudan sınıfın kendisine ait olan üyelere ihtiyaç duyarız. Bunlara statik üyeler (static members) denir ve static anahtar kelimesi ile tanımlanırlar.
Statik Alanlar/Özellikler: Sınıfın tüm örnekleri tarafından paylaşılır. Değeri tüm örnekler için aynıdır. Bir sayaç, bir sabit değer (ama const daha iyi olabilir), yapılandırma ayarı gibi şeyler için kullanılabilir.
Statik Metotlar: Belirli bir nesne örneği oluşturmadan, doğrudan sınıf adı üzerinden çağrılırlar. Genellikle yardımcı (utility) fonksiyonlar veya fabrika (factory) metotları (nesne oluşturma metotları) olarak kullanılırlar. Statik metotlar, örnek (instance) üyelerine (this kullanarak) doğrudan erişemezler, çünkü belirli bir nesne bağlamında çalışmazlar. Sadece diğer statik üyelere erişebilirler.
Statik Yapıcı (Static Constructor): Sınıfın ilk kez kullanıldığı (ilk nesne oluşturulduğunda veya ilk statik üyeye erişildiğinde) anda sadece bir kez otomatik olarak çalışan özel bir yapıcıdır. Genellikle statik alanları başlatmak için kullanılır. Parametre alamaz ve erişim belirleyicisi olmaz. static SinifAdi() { … }
Örnek:
public class AyarlarYoneticisi
{
// Statik alan (tüm uygulama için tek bir kopya)
private static int _maxBaglantiSayisi = 10;
private static readonly string _varsayilanTema; // Salt okunur statik alan
// Statik yapıcı (ilk kullanımda bir kez çalışır)
static AyarlarYoneticisi()
{
Console.WriteLine("Statik yapıcı çalıştı!");
// Statik alanları başlat
_varsayilanTema = "Açık";
// Belki bir dosyadan ayarları oku...
}
// Statik özellik
public static int MaxBaglantiSayisi
{
get { return _maxBaglantiSayisi; }
// set { _maxBaglantiSayisi = value; } // İstersek ayarlanabilir yapabiliriz
}
public static string VarsayilanTema => _varsayilanTema; // C# 6+
// Statik metot (yardımcı fonksiyon)
public static bool AyarGecerliMi(string ayarAdi)
{
// Bu metot örnek alanlarına (_bakiye gibi) erişemez!
return !string.IsNullOrEmpty(ayarAdi);
}
// Örnek (instance) metodu (statik üyelere erişebilir)
public void MevcutAyarlariGoster()
{
Console.WriteLine($"Maks Bağlantı: {MaxBaglantiSayisi}"); // Statik özelliğe erişim
Console.WriteLine($"Varsayılan Tema: {VarsayilanTema}");
}
}
// Kullanım
Console.WriteLine(AyarlarYoneticisi.MaxBaglantiSayisi); // Nesne oluşturmadan statik üyeye erişim
Console.WriteLine(AyarlarYoneticisi.VarsayilanTema);
bool gecerli = AyarlarYoneticisi.AyarGecerliMi("Veritabanı"); // Statik metot çağırma
Console.WriteLine(gecerli);
AyarlarYoneticisi ayarlar1 = new AyarlarYoneticisi();
ayarlar1.MevcutAyarlariGoster(); // Örnek metodu çağırır (statik üyelere erişir)
System.Math ( Math.PI, Math.Sin()) veya System.Console (Console.WriteLine()) gibi sınıflar tamamen statik üyelerden oluşur ve örnekleri oluşturulmaz.
Bölüm 5: Erişim Belirleyiciler (Access Modifiers)
Erişim belirleyiciler, sınıf üyelerinin (alanlar, özellikler, metotlar, yapıcılar) ve sınıfların kendilerinin kodun diğer bölümlerinden ne kadar erişilebilir olduğunu kontrol eder. Kapsülleme (encapsulation) prensibinin temelini oluştururlar.
public: Üyeye veya türe her yerden (aynı derleme veya farklı derlemelerden) erişilebilir. En az kısıtlayıcıdır.
private (Varsayılan — Sınıf üyeleri için): Üyeye sadece tanımlandığı sınıfın içinden erişilebilir. En kısıtlayıcıdır. Kapsülleme için genellikle alanlar private yapılır.
protected: Üyeye tanımlandığı sınıfın içinden ve o sınıftan türeyen (miras alan) alt sınıfların içinden erişilebilir.
internal (Varsayılan — Türler için): Türe veya üyeye sadece tanımlandığı aynı derleme (assembly — .dll veya .exe) içinden erişilebilir. Farklı bir projeden (farklı derleme) erişilemez.
protected internal: Üyeye aynı derleme içinden VEYA farklı derlemedeki türetilmiş sınıflardan erişilebilir ( protected OR internal).
private protected (C# 7.2+): Üyeye sadece aynı derleme içindeki türetilmiş sınıflardan erişilebilir ( protected AND internal).
Kural: Genellikle, üyeleri mümkün olduğunca kısıtlı (private) tutmak ve sadece dışarıya açılması gereken işlevselliği public (veya duruma göre protected/internal) yapmak iyi bir OOP pratiğidir (En Az Ayrıcalık Prensibi — Principle of Least Privilege). Alanlar neredeyse her zaman private olmalı ve erişim public (veya kontrollü) özellikler üzerinden sağlanmalıdır.
Bölüm 6: Nesne Yönelimli Prensipler ve Sınıflar
Sınıflar, temel OOP prensiplerini uygulamak için araçlar sunar:
Kapsülleme (Encapsulation): İlgili veri (alanlar) ve davranışları (metotlar) tek bir birimde (sınıf) birleştirmek ve veriye doğrudan erişimi kısıtlayarak ( private alanlar) sadece kontrollü arayüzler ( public özellikler ve metotlar) üzerinden etkileşim sağlamaktır. Bu, iç uygulamanın detaylarını gizler (information hiding) ve nesnenin durumunun tutarlı kalmasını sağlar.
Kalıtım (Inheritance): Bir sınıfın (alt sınıf/derived class) başka bir sınıfın (üst sınıf/base class) özelliklerini ve metotlarını devralmasıdır. Kod tekrarını önler ve “bir türüdür” (is-a) ilişkisi kurar. C#’ta class AltSinif : UstSinif söz dizimi ile yapılır. base anahtar kelimesi ile üst sınıfın üyelerine erişilebilir. C# tekli kalıtımı (single inheritance) destekler (bir sınıf sadece bir sınıftan miras alabilir), ancak çoklu arayüz kalıtımını (multiple interface inheritance) destekler.
Çok Biçimlilik (Polymorphism): Kelime anlamı “birçok şekil”dir. OOP bağlamında genellikle iki anlama gelir:
Metot Aşırı Yükleme (Method Overloading): Aynı sınıf içinde, aynı isimde ancak farklı parametre listelerine (sayı, tür veya sıra olarak) sahip birden fazla metot tanımlama yeteneğidir. Derleyici, çağrıdaki argümanlara göre hangi metodun çalıştırılacağını belirler.
Metot Geçersiz Kılma (Method Overriding): Alt sınıfın, üst sınıftan miras aldığı bir metodu ( virtual, abstract veya override olarak işaretlenmiş) kendi özel uygulamasıyla yeniden tanımlamasıdır. Bu, üst sınıf türündeki bir referansın aslında alt sınıf örneğini tuttuğu durumlarda, nesnenin gerçek türüne uygun metodun çalıştırılmasını sağlar (virtual ve override anahtar kelimeleri kullanılır). Bu, “birçok şekil” fikrinin en belirgin olduğu yerdir.
Soyutlama (Abstraction): Nesnenin karmaşık iç detaylarını gizleyerek sadece gerekli arayüzü dışarıya sunmaktır. Kullanıcılar, nesnenin nasıl çalıştığını bilmeden onu kullanabilirler. abstract sınıflar ve interface’ler soyutlamayı uygulamak için önemli araçlardır.
Bölüm 7: Sonuç — OOP’nin Temel Taşı
Sınıflar ve Nesneler, C# programlamanın ve Nesne Yönelimli Programlamanın temelini oluşturur. Sınıflar, nesnelerin yapısını ve davranışını tanımlayan planlarken, nesneler bu planlardan oluşturulan, durumu (veriyi) ve davranışı (metotları) olan somut örneklerdir.
Alanlar, özellikler, metotlar ve yapıcılar gibi sınıf üyeleri, nesnelerin iç yapısını ve dış arayüzünü oluşturur. Erişim belirleyiciler, kapsüllemeyi sağlayarak kodun güvenliğini ve modülerliğini artırır. Statik üyeler, belirli bir nesneye değil, sınıfın kendisine ait olan paylaşılan veri ve işlevsellik sağlar. this anahtar kelimesi, bir nesnenin kendi üyelerine erişmesi için kritik bir referanstır.
class söz dizimi, prototip tabanlı dillerdeki kadar esnek olmasa da, C#’a yapılandırılmış, güçlü tipli ve anlaşılır bir OOP modeli kazandırır. Kapsülleme, kalıtım ve çok biçimlilik gibi OOP prensiplerini sınıflar aracılığıyla etkin bir şekilde uygulamak, büyük, karmaşık ve sürdürülebilir yazılımlar geliştirmenin anahtarıdır. Sınıflara ve nesnelere hakim olmak, C# dilinde yetkinleşmenin en önemli adımıdır.
Abdulkadir Güngör - Kişisel WebSite
Abdulkadir Güngör - Kişisel WebSite
Abdulkadir Güngör - Özgeçmiş
Github
Github
Linkedin