C# – Abstract Class (Soyut Sınıf) Nedir?

Teknik olarak bir açıklama yapmak gerekirse;

Nesne tabanlı programlamada sınıf hiyerarşisi oluşturulurken, bazen en tepede bulunan sınıf türünden nesneler programcılar için anlamlı olmayabilir. Hiyerarşinin en tepesinde bulunan sınıfın kendisinden türetilecek olan alt sınıflar için ortak bir arayüz (interface) görevi yapması istenebilir. Bunun için çözüm olarak oluşturulan metotlara ve sınıflara soyut metot (abstract method) ya da soyut sınıf (abstract class) denir.

Teknik açıklamayı yaptıktan sonra açıklamaya şöyle devam edelim. Bir önce ki yazım da Inhertince kalıtım konusunu değinmiştim. Abstract classlarda aslında bir inherittır. Abstract Class, inhertince konusunda işlediğimiz ortak özellikli olan Class’lara base class olma rolünü üstlenir.

Bir class için pek çok ortak yön olarak özellikleriniz olduğunu düşünelim ve aynı özellikleri de içinde tutan başka classlarınızın olduğu bir senaryo düşünün. Böyle bir senaryoda tekrardan aynı özellikleri yazmak yerine base (yani abstract) class tanımlayıp buradan türetilmiş sınıflara kodumuzun daha efektif olmasını sağlıyoruz.

Bunu temel matematikte gördüğümüz kümelerde keşisisim konusuna benzetebiliriz.

Abstract Class Kullanımı

Bir sınıfın abstract olduğunu bildirmek için oluşturduğumuz sınıfın önüne abstrack anahtar kelimesini ekleriz. Bu şekilde bir abstract class oluşturduğumuzu derleyicimize bildirmiş olur.

abstract class MyClass
{
}

Burada abstrack classın en önemli özelliği; abstract sınıflar tamamen kalıtım amaçlı geliştirildiğinden dolayı abstrack sınıflardan nesne oluşturulamaz. yani diğer bir deyişle sınıflar gibi new lenemezler.

Method oluşumuda yine aynı şekilde erişim belirleyicisinden sonra abstrack anahtar kelimesi kullanılarak oluşturulur.

Abstract Method Nedir?

public abstract void MyAbstractMethod(); 

Abstrack methodların iki önemli özelliği bulunur.

  • Abstrack methodların gövdesi olmaz veya bir başka değişle tamamlanmamış methodlardır. Zaten amaçta budur. Bu methodun tamamlanmış olması zaten bu disiplene aykırıdır. Çünkü kalıtım yoluyla türettiğimizde ortak özelliklerden farklı olan özelliği abstrack methodu override ederek kendi sınıfımızın özelliğine göre derleyeceğiz.
  • Diğer bir konuda private erişim belirleyeceği ile tanımlanamazlar.

Abstract Sınıfların Normal Sınıflardan Farkı Nedir?

  • Fark 1: Normal sınıflar içerisinde metot bildirimi yapılamazken, Abstract sınıflar içerisinde tıpkı arayüzler de olduğu gibi metot bildirimi yapılabilir. Bildirimi yapılan metotlar, Abstract sınıftan türeyen sınıflar içerisinde tanımlanmak zorundadır.
  • Fark 2: Normal sınıflardan “new()” anahtar sözcüğü ile nesneler oluşturulabilir ancak Abstract sınıflar tamamen kalıtım amaçlı geliştirildiğinden Abstract sınıflardan nesne oluşturulamaz.
TuretilmisSinif turetilmisSinif = new TuretilmisSinif(); (Doğru)
TemelSinif temelSinif = new TemelSinif();                (Yanlış)

Abstract Sınıfların Arayüzlerden (Interface) Farkı Nedir?

  • Fark 1: Arayüzlerde sadece metot bildirimi yapılabilirken Abstract sınıflarda hem metot bildirimi yapılabilir hem de metot tanımlanabilir.
  • Fark 2: Bir sınıfa sadece bir tane Abstract sınıf inherit edilebilir ancak aynı sınıfa birden fazla arayüz implement edilebilir.

Örnek Abstract Kullanımı

İçerisinde database bağlantısı gerçekleştireceğimiz özellikleri methodları barından bir classımız olduğunu düşünelim daha sonra projemizin ilerlerleyen aşamasında farklı veri tabanlarına da bağlantı yapma ihtayacı geliştiğini varsayalım bu tip durumda aynı özelliklerde bir den fazla class yazma durumu ortaya çıkar. Bu tip durumları önlemek için bu tip senaryolarda clasımızı abstrack olarak tanımlarsak tekrardan classlar yazmadan ortak özelliklerden faydanalabiliriz.

Aşağıda ki örneğimizde database adında bir abstrack classımız bulunmakta bütün bağlantı modellerinde ortak olarak add methodu bulunur bu özellikleri abstrack olarak tanımlayıp diğer classlarımız da ortak kullanımını içeren ayrıca classların kendilerine özgü delete methodu içerdiği bir senaryonun örnek kod dizimi gösterilmiştir.

    abstract class Database
    {
        //Tamamlanmış method
        public void Add()
        {
            Console.WriteLine("Added by Default");
        }
        //Tamamlanmamış methodlar.
        public abstract void Delete();

    }

    class SqlServer : Database
    {
        public override void Delete()
        {
            //throw new NotImplementedException();
            Console.WriteLine("Deleted by Sql");
        }
    }

    class MySqlServer : Database
    {
        public override void Delete()
        {
            //throw new NotImplementedException();
            Console.WriteLine("Deleted by MySql");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Database database = new SqlServer();
            database.Add();
            database.Delete();
            Console.WriteLine("***********************\n");

            SqlServer sqlServer = new SqlServer();
            sqlServer.Add();
            sqlServer.Delete();
            Console.WriteLine("***********************\n");

            Database database2 = new MySqlServer();
            database2.Add();
            database2.Delete();
            Console.WriteLine("***********************\n");

            MySqlServer mySqlServer = new MySqlServer();
            mySqlServer.Add();
            mySqlServer.Delete();

            Console.ReadLine();
        }
    }