Merhaba, bu yazıda C# abstraction (soyutlama) kavramını anlatacağım. Soyutlama, nesne yönelimli programlamanın temel prensiplerinden biridir ve karmaşık bir sistemi daha basit ve anlaşılır hale getirmek için kullanılır. Soyutlama sayesinde, bir sınıfın veya arayüzün sadece dışarıya sunmak istediği özellikleri ve davranışları tanımlayabilir, geri kalan detayları gizleyebiliriz. Böylece, sistemin nasıl çalıştığına değil, ne yaptığına odaklanabiliriz.
Soyutlama nasıl yapılır? C# dilinde soyutlama yapmanın iki yolu vardır: sınıflar (classes) ve arayüzler (interfaces). Sınıflar, bir nesnenin özelliklerini (fields) ve davranışlarını (methods) tanımlayan yapılar olarak bilinir. Sınıfların içindeki özellik ve davranışlara erişim belirleyicileri (access modifiers) ile belirleyebiliriz. Erişim belirleyicileri, public, private, protected, internal ve protected internal olmak üzere beş tanedir. Bu erişim belirleyicileri sayesinde, sınıfın hangi özellik ve davranışlarının dışarıya açık olacağını, hangilerinin gizli kalacağını belirleyebiliriz. Örneğin, bir Araba sınıfı tanımlayalım:
class Araba {
//Özellikler
private string marka;
private string model;
private int yil;
private int hiz;
//Davranışlar
public void Hizlan(int artis) {
hiz += artis;
}
public void Yavasla(int azalis) {
hiz -= azalis;
}
public void BilgiVer() {
Console.WriteLine("Marka: " + marka);
Console.WriteLine("Model: " + model);
Console.WriteLine("Yıl: " + yil);
Console.WriteLine("Hız: " + hiz);
}
}
Bu sınıfta, marka, model, yil ve hiz özellikleri private olarak tanımlanmıştır. Bu demek oluyor ki, bu özelliklere sadece sınıfın içinden erişilebilir, dışarıdan erişilemez. Böylece, bu özelliklerin değerleri korunur ve istenmeyen değişikliklerden kaçınılır. Bu özelliklere erişmek için public olarak tanımlanmış olan Hizlan, Yavasla ve BilgiVer davranışları kullanılır. Bu davranışlar, sınıfın dışarıya sunduğu arayüzü oluşturur. Bu arayüz sayesinde, Araba nesnelerinin nasıl çalıştığına değil, ne yaptığına odaklanabiliriz.
Arayüzler ise soyutlama yapmanın diğer bir yoludur. Arayüzler, sadece davranışların tanımlandığı ama hiçbir şekilde uygulanmadığı yapılar olarak bilinir. Arayüzlerin amacı, farklı sınıfların ortak davranışlarını belirtmek ve bu sınıflara bu davranışları uygulamak için bir sözleşme sunmaktır. Arayüzler sayesinde, farklı sınıflar arasında ortak bir arayüz oluşturabilir ve bu sınıfları aynı şekilde kullanabiliriz. Örneğin, bir ICalisabilir arayüzü tanımlayalım:
interface ICalisabilir {
void Calis();
void Dur();
}
Bu arayüzde, Calis ve Dur adında iki davranış tanımlanmıştır ama hiçbir şekilde uygulanmamıştır. Bu arayüzü uygulayan sınıflar, bu davranışları kendi içlerinde nasıl uygulayacaklarını belirtmek zorundadırlar. Örneğin, Araba sınıfımızı bu arayüzü uygulayacak şekilde değiştirelim:
class Araba : ICalisabilir {
//Özellikler
private string marka;
private string model;
private int yil;
private int hiz;
//Davranışlar
public void Hizlan(int artis) {
hiz += artis;
}
public void Yavasla(int azalis) {
hiz -= azalis;
}
public void BilgiVer() {
Console.WriteLine("Marka: " + marka);
Console.WriteLine("Model: " + model);
Console.WriteLine("Yıl: " + yil);
Console.WriteLine("Hız: " + hiz);
}
//Arayüzden gelen davranışlar
public void Calis() {
Console.WriteLine("Araba çalışıyor.");
}
public void Dur() {
Console.WriteLine("Araba durdu.");
hiz = 0;
}
}
Bu şekilde, Araba sınıfı ICalisabilir arayüzünü uygulamış olur ve bu arayüzden gelen Calis ve Dur davranışlarını kendi içinde tanımlar. Bu sayede, Araba sınıfı da bir ICalisabilir nesnesi olarak kabul edilir ve bu arayüzü kullanan diğer sınıflarla ortak bir arayüz paylaşır. Örneğin, bir de Bisiklet sınıfı tanımlayalım:
class Bisiklet : ICalisabilir {
//Özellikler
private string renk;
private int vites;
//Davranışlar
public void VitesDegistir(int yeniVites) {
vites = yeniVites;
}
public void BilgiVer() {
Console.WriteLine("Renk: " + renk);
Console.WriteLine("Vites: " + vites);
}
//Arayüzden gelen davranışlar
public void Calis() {
Console.WriteLine("Bisiklet çalışıyor.");
}
public void Dur() {
Console.WriteLine("Bisiklet durdu.");
vites = 0;
}
}
Bu sınıf da ICalisabilir arayüzünü uygular ve bu arayüzden gelen davranışları kendi içinde tanımlar. Bu sayede, Bisiklet sınıfı da bir ICalisabilir nesnesi olarak kabul edilir ve bu arayüzü kullanan diğer sınıflarla ortak bir arayüz paylaşır. Şimdi, bu iki sınıfı aynı şekilde kullanalım:
class Program {
static void Main(string[] args) {
//ICalisabilir tipinde iki değişken tanımlıyoruz
ICalisabilir calisan1;
ICalisabilir calisan2;
//Bu değişkenlere Araba ve Bisiklet nesneleri atıyoruz
calisan1 = new Araba();
calisan2 = new Bisiklet();
//Bu nesnelerin Calis ve Dur davranışlarını çağırıyoruz
calisan1.Calis();
calisan2.Calis();
calisan1.Dur();
calisan2.Dur();
//Çıktı:
//Araba çalışıyor.
//Bisiklet çalışıyor.
//Araba durdu.
//Bisiklet durdu.
...
...
...
Gördüğünüz gibi, farklı tipteki nesneleri aynı şekilde kullanabildik. Bu, soyutlamanın sağladığı bir avantajdır. Arayüzler sayesinde, nesnelerin nasıl çalıştığına değil, ne yaptığına odaklanabiliriz.
Soyutlama, programlama dilinin sağladığı bir özelliktir ve programcının işini kolaylaştırır. Soyutlama sayesinde, programcılar karmaşık problemleri daha basit ve anlaşılabilir parçalara bölebilirler. Bu, kodun okunabilirliğini artırır ve daha az hata yapma olasılığını sağlar.
Ayrıca, soyutlama sayesinde programcılar, tekrar kullanılabilir kod blokları oluşturabilirler. Bir kez yazılan soyut kod parçaları, farklı projelerde veya farklı bölümlerde tekrar kullanılabilir, böylece kodun yeniden kullanılabilirliği ve bakımı kolaylaşır.
Soyutlama aynı zamanda programcıların kodu daha esnek ve genişletilebilir hale getirmesini sağlar. Yeni gereksinimler eklendiğinde veya değişiklikler yapıldığında, soyut yapılar sayesinde kodu değiştirmek ve adapte etmek daha kolay olur.
Bu nedenle, soyutlama programlamada önemli bir prensiptir ve programcıların daha etkili ve verimli kod yazmalarına yardımcı olur. Programlama dillerinin sağladığı bu özellik sayesinde, karmaşık problemler daha rahat çözülebilir ve daha güvenilir yazılımlar geliştirilebilir.
Bu yazıda C#’ta soyutlama konusunu anlattım. Umarım yararlı olmuştur. Soru veya görüşlerinizi yorumlarda paylaşabilirsiniz.
C# ile ilgili diğer yazılarım için: C# – Bizneyapiyoruzki