C# Encapsulation, Kalıtım, Polimorfizm
C#’ta encapsulation, kalıtım ve polimorfizmi öğrenin. OOP’nin temel prensiplerini örneklerle anlayıp doğru kullanımını keşfedin.
Nesne Yönelimli Programlama (OOP), yazılım geliştirmede tekrar kullanılabilir, bakımı kolay ve anlaşılır kodlar yazabilmek için geliştirilmiş bir yaklaşımdır. OOP’nin üç temel yapı taşı şunlardır:
- Encapsulation (Kapsülleme) → Veriyi gizleme ve kontrollü erişim sağlama
- Inheritance (Kalıtım) → Ortak davranışların alt sınıflara aktarılması
- Polymorphism (Polimorfizm) → Aynı metodun farklı nesnelerde farklı davranması
Bu üç özellik birlikte kullanıldığında, yazılım projelerinde sağlam bir mimari oluşturulabilir. Şimdi her birini tek tek inceleyelim.
Encapsulation (Kapsülleme)
Kapsülleme, bir sınıfın iç yapısını dış dünyadan gizleyerek sadece gerekli kısımların erişilebilir olmasını sağlar.
Böylece veriye doğrudan müdahale edilmesi engellenir, hatalar azaltılır ve sınıfın iç mantığı değişse bile dışarıya yansımaz.
C#’ta private, protected, internal, public gibi erişim belirleyicilerle uygulanır.
Genellikle field’lar gizlenir, dışarıya property veya method aracılığıyla kontrollü erişim sağlanır.
public class BankAccount
{
private decimal _balance; // doğrudan erişim kapalı
public decimal Balance
{
get => _balance;
private set => _balance = value;
}
public void Deposit(decimal amount)
{
if (amount <= 0)
throw new ArgumentException("Tutar sıfırdan büyük olmalı.");
Balance += amount;
}
public void Withdraw(decimal amount)
{
if (amount > Balance)
throw new InvalidOperationException("Yetersiz bakiye.");
Balance -= amount;
}
}
Bu örnekte bakiye (_balance) doğrudan değiştirilemez.
Kullanıcı yalnızca Deposit ve Withdraw metotları üzerinden işlem yapabilir.
Böylece yanlış kullanım önlenir ve veri güvenliği sağlanır.
Inheritance (Kalıtım)
Kalıtım, bir sınıfın başka bir sınıftan özellik ve davranış devralmasını sağlar. Böylece ortak kodlar tek bir yerde toplanır ve tekrar kullanılabilir hale gelir. Üst (base) sınıf genel davranışları tanımlar, alt (derived) sınıflar ise özelleştirilmiş davranışları ekler.
public class Animal
{
public string Name { get; set; } = string.Empty;
public void Eat()
{
Console.WriteLine($"{Name} yemek yiyor.");
}
}
public class Dog : Animal
{
public void Bark()
{
Console.WriteLine($"{Name} havlıyor.");
}
}
public class Cat : Animal
{
public void Meow()
{
Console.WriteLine($"{Name} miyavlıyor.");
}
}
class Program
{
static void Main()
{
Dog d = new Dog { Name = "Karabaş" };
d.Eat(); // Animal'dan miras
d.Bark(); // Dog'a özel
Cat c = new Cat { Name = "Tekir" };
c.Eat(); // Animal'dan miras
c.Meow(); // Cat'e özel
}
}
Burada hem Dog hem de Cat, Animal sınıfından türedi.
Ortak davranış olan Eat() sadece bir kez yazıldı ve tüm alt sınıflarda kullanılabilir oldu.
Polymorphism (Polimorfizm)
Polimorfizm, aynı metodun farklı nesnelerde farklı şekilde çalışabilmesi demektir. İki tür polimorfizm vardır:
- Compile-time Polymorphism: Metot aşırı yükleme (method overloading) ile sağlanır.
- Runtime Polymorphism: Sanal metot (
virtual) ve geçersiz kılma (override) ile sağlanır.
public class Animal
{
public string Name { get; set; } = string.Empty;
public virtual void Speak()
{
Console.WriteLine($"{Name} ses çıkarıyor.");
}
}
public class Dog : Animal
{
public override void Speak()
{
Console.WriteLine($"{Name} havlıyor.");
}
}
public class Cat : Animal
{
public override void Speak()
{
Console.WriteLine($"{Name} miyavlıyor.");
}
}
class Program
{
static void Main()
{
Animal a1 = new Dog { Name = "Karabaş" };
Animal a2 = new Cat { Name = "Tekir" };
a1.Speak(); // Karabaş havlıyor.
a2.Speak(); // Tekir miyavlıyor.
}
}
Aynı Speak() çağrısı, nesnenin türüne göre farklı çıktı üretir.
Bu esneklik, OOP’nin en güçlü yönlerinden biridir.
Örnek: Kitap Türleri
Bir kütüphane uygulamasında kitapları modelleyelim.
Ortak özellikler Book sınıfında tanımlanır, her alt sınıf ise kendine özgü bilgileri ekler veya
PrintInfo() metodunu farklı şekilde uygular.
Ayrıca Author ve Publisher sınıfları ile kitaplara ait yazar ve yayınevi bilgileri ayrı nesnelerde tutulur.
Bu yapı, hem kalıtım hem de polimorfizmin bir arada nasıl kullanılacağını gösterir.
public class Author
{
public string Name { get; set; } = string.Empty;
public string Country { get; set; } = string.Empty;
}
public class Publisher
{
public string Name { get; set; } = string.Empty;
public string Address { get; set; } = string.Empty;
}
public abstract class Book
{
public string Title { get; set; } = string.Empty;
public Author BookAuthor { get; set; } = new Author();
public Publisher BookPublisher { get; set; } = new Publisher();
public int Pages { get; set; }
public string ISBN { get; set; } = string.Empty;
public int Year { get; set; }
// Alt sınıflarda özelleştirilecek
public abstract void PrintInfo();
}
public class ScienceBook : Book
{
public string Field { get; set; } = string.Empty; // Fizik, Kimya, Biyoloji
public override void PrintInfo()
{
Console.WriteLine($"[Bilim Kitabı] {Title} - {BookAuthor.Name}, {Pages} sayfa");
Console.WriteLine($"Alan: {Field}, ISBN: {ISBN}, Yayınevi: {BookPublisher.Name}");
}
}
public class HistoryBook : Book
{
public string Period { get; set; } = string.Empty; // Antik Çağ, Orta Çağ vb.
public override void PrintInfo()
{
Console.WriteLine($"[Tarih Kitabı] {Title} - {BookAuthor.Name}, {Pages} sayfa");
Console.WriteLine($"Dönem: {Period}, ISBN: {ISBN}, Yayınevi: {BookPublisher.Name}");
}
}
class Program
{
static void Main()
{
var publisher = new Publisher { Name = "Bilgi Yayınları", Address = "İstanbul" };
var author1 = new Author { Name = "Albert Einstein", Country = "Almanya" };
var author2 = new Author { Name = "Halil İnalcık", Country = "Türkiye" };
Book b1 = new ScienceBook
{
Title = "Görelilik Kuramı",
BookAuthor = author1,
BookPublisher = publisher,
Pages = 250,
ISBN = "123-456-789",
Year = 1920,
Field = "Fizik"
};
Book b2 = new HistoryBook
{
Title = "Osmanlı İmparatorluğu",
BookAuthor = author2,
BookPublisher = publisher,
Pages = 500,
ISBN = "987-654-321",
Year = 1973,
Period = "Osmanlı Dönemi"
};
b1.PrintInfo();
Console.WriteLine();
b2.PrintInfo();
}
}
Avantajları
- Encapsulation: Veri güvenliği sağlar, hatalı kullanımın önüne geçer.
- Inheritance: Kod tekrarını azaltır, hiyerarşik bir yapı kurar.
- Polymorphism: Esnek ve genişletilebilir bir mimari oluşturur.
TL;DR
- Encapsulation: İç veriyi gizleyip kontrollü erişim sağlar.
- Inheritance: Üst sınıfın özellik ve davranışları alt sınıflara aktarılır.
- Polymorphism: Aynı metod farklı alt sınıflarda farklı davranış gösterebilir.
İlişkili Makaleler
C# Constructor, Destructor ve this Kullanımı
C#’ta constructor, destructor ve this anahtar kelimesinin kullanımını öğrenin. Nesne yaşam döngüsü ve sınıf içi erişim örneklerle anlatılıyor.
C# Dependency Injection Temelleri
C#’ta Dependency Injection kavramını öğrenin. Bağımlılıkların yönetimi, gevşek bağlılık ve test edilebilirlik örneklerle anlatılıyor.
C# ile SOLID Prensipleri
C# örnekleriyle SOLID prensiplerinin uygulanışı: daha esnek, sürdürülebilir ve test edilebilir kod tasarımları.
C# Interface ve Abstract Sınıflar
C#’ta interface ve abstract sınıfları öğrenin. Farklarını, ne zaman hangisini kullanacağınızı ve tasarım senaryolarını örneklerle keşfedin.
C# Record Types ve Immutable Nesneler
C# record type ve immutable nesneleri öğrenin. Değişmez veri modeli, value equality ve with ifadeleriyle modern C# pratiklerini keşfedin.
C# Sınıf (Class), Object, Property ve Metotlar
C#’ta class, object, property ve metot kavramlarını öğrenin. Nesne yönelimli programlamanın temel yapı taşları örneklerle açıklanıyor.
C# Struct (Yapılar) – Class ile Farkları
C#’ta struct ve class arasındaki farkları öğrenin. Bellek modeli, kalıtım, boxing ve performans karşılaştırmalarıyla açıklanıyor.