Makale Özeti

Abstract class’lar, .NET üzerinde nesne yönelimli programlama konusunda önemli kavramlardan birini teşkil eder. Yazımızda abstract class'larla ilgili temel özellikleri, kullanım alanları ve diğer yakın kavramlarla olan benzerlik ve ayrımları inceleyeceğiz.

Makale




C# Uygulamalarında Abstract Class Kullanımı

Abstract class’lar, oluşturulması istenen class’ların sadece base class olarak davranması ve üzerinden bir instance oluşturulmamasının istendiği durumlarda kullanılır. C#’da bu fonksiyonaliteyi sağlamak için abstract anahtar sözcüğünü kullanmak yeterlidir.

Örnek bir abstract class yazım şekli:

abstract class absClass
{
}

Abstract class’lar içinde abstract metodlar olabileceği gibi abstract olmayan (non-abstract) metodlar da olabilir. Abstract metodlar abstract class içinde implement edilmezler yani içlerinde herhangibir kod bloku barındırmazlar. Kendilerini inherit edecek olan class’lar tarafından yazılmaları gerekmektedir. Örnek bir abstract metod yazım şekli:

abstract class absClass
{
   public abstract void abstractMethod();
}

Abstract class’lar içinde mutlaka abstract bir metod yazılması gibi bir zorunluluk yoktur. Yani ihtiyaca göre abstract bir metod sadece non abstract metodlardan da oluşabilir. Örnek bir non abstract class yazım şekli:

abstract class absClass
{
   public void NonAbstractMethod()
   {
      Console.WriteLine("NonAbstract Method");
   }
}

Fakat genel kullanımı düşünecek olursak abstract class’lar içinde hem abstract hem de non-abstract metodları bir arada sıklıkla kullanıyoruz. Örnek kullanım:

//Creating an Abstract Class
abstract class absClass
{
    //A Non abstract method
   public int AddTwoNumbers(int Num1, int Num2)
   {
      return Num1 + Num2;
   }

   //An abstract method, to be
   //overridden in derived class
   public abstract int MultiplyTwoNumbers(int Num1, int Num2);
}

Şimdiki örneğimizi ise abstract class’ları biraz daha detaylandırmak için verelim.

//Abstract Class1
abstract class absClass1
{
    public abstract int AddTwoNumbers(int Num1, int Num2);
    public abstract int MultiplyTwoNumbers(int Num1, int Num2);
}

//Abstract Class2
abstract class absClass2:absClass1
{
   //Implementing AddTwoNumbers
    public override int AddTwoNumbers(int Num1, int Num2)
    {
        return Num1+Num2;
    }
}

//Derived class from absClass2
class absDerived:absClass2
{
    //Implementing MultiplyTwoNumbers
    public override int MultiplyTwoNumbers(int Num1, int Num2)
    {
        return Num1*Num2;
    }
}


Örnekte inceleyebileceğimiz gibi, abstract class’lardan yine bir abstract class da türeyebilir. absClass1 isimli base abstract class içinde 2 adet abstract metod tanımladık. Daha önce söylediğimiz kuralı uygulayarak abstract metod’ları base class içinde implemente etmedik. absClass2 isimli class absClass1’i inherit etti ve tercihen abstract bir class olarak yaratıldı. Base class’ından aldığı AddTwoNumbers abstract metodunu override ederek kendi içinde implement etti. Abstract metod’ların amaçları türeyen class’larda implemente edilmek olduğundan implicit olarak virtual özelliği taşırlar. absDerived class’ı ise absClass1’den türeyen absClass2'yi inherit etti ve absClass2'nin de kendi base class'ından inherit ettiği MultiplyTwoNumbers metodunu implement ederek tercihen non abstract bir class olarak yaratılmış oldu.

Abstract class’larla ilgili birkaç önemli kuraldan da bahsedelim. Object oriented kuralları ile mantıksal olarak da doğrulayacağınız bu kurallar şu şekilde:
1. Abstract class’lar sealed keyword ile kullanılamazlar. Sealed class’lar kendilerinden inherit olan class’lar türetilmesine izin vermedikleri için abstract class’ların temel kullanım amacına ters düşerler, bu nedenle abstract class’larda sealed keyword kullanılamaz.

2. Abstract metodlar private keyword ile kullanılamazlar. Private metodlar, türemiş class’lar tarafından inherit edilemediklerinden dolayı abstract metod kullanım mantığı ile çakışırlar, o nedenle abstract metodlar private access modifier’a sahip olamazlar.

3. Abstract metodlar sadece abstract class’lar içinde tanımlanabilir. Abstract bir metodun sahip olduğu access modifier ile onu inherit eden class’ın access modifier’ı aynı olmak zorundadır. Sözgelimi, örnekte kullandığımız absClass1 içindeki abstract metod AddTwoNumbers metodu protected bir metod olsa idi, onu inherit eden absClass2 içindeki AddTwoNumbers metodu da protected olmak zorunda olacaktı.

4. Abstract metod’lar virtual keyword ile kullanılamazlar. Az önceki örneğimizde de bahsettiğimiz gibi abstract metod’ların amaçları türeyen class’larda implemente edilmek olduğundan implicit olarak virtual özelliği taşırlar, explicit olarak virtual keyword yazılması durumunda hata alırlar.

5. Abstract metodlar static keyword ile yazılamazlar. Static metod ve özellikler class metodları veya özellikleri olarak adlandırılırlar (static olmayan metodlar ise instance metodlarıdır) ve class üzerinden instance yaratılmadan evvel çalışırlar.

Abstract metodları türemiş class’ların implement etmesi zorunluğundan dolayı, bir abstract class’ın non abstract metodları static olabiliyorken, abstract metodlar ile static keyword kullanılamaz.

Son olarak abstract class’lar ile interface’ler arasındaki farklara değinelim.

• Abstract class’lar, hem abstract hem de non abstract metodlar barındırabildiği halde, interface içindeki tüm metodlar implicit olarak abstract özelliği taşır ve kendisini implement edecek class’lar tarafından mutlaka implement edilmeleri gerekir. (Sadece abtsract member’lardan oluşan bir abstract class ile interface aynı etkiyi yaratır)

• Interface içindeki tüm öğeler public iken, abstract class’lar içinde protected, static metodlar da olabilir.

• Bir class, birden fazla interface implemente edebilirken sadece bir tane abstract class’tan inherit olabilir.

Projelerimizde abstract class veya interface kullanma durumu ihtiyaca göre değişkenlik gösterir. Bazı durumlarda abstract class, bazı durumlarda interface bazı durumlarda ise her ikisinin kombinasyonunu kullanabiliriz.

Onur Kulabaş
Yazılım Danışmanı

Sorularınız için onurkulabas@yahoo.com