Interface mi, Abstract mı?

Genellikle Nesneye Yönelik Programlamaya yeni başlayanların kafasındaki büyük soru işaretlerinden bazıları "Interface ile Abstract arasındaki farklar nelerdir?, Ne zaman Interface ne zaman Abstract sınıfları kullanmalıyız ? …." gibi sorulardır.

Acı ve komik bir anımdan bahsetmeden olmaz. Okulda Java hocama neden Interface kullanırız diye sorduğumda bana "Genelde pek kullanılmaz. Fakat benim daha önce çalıştığım bilmem ne işyerinde bi abi interface kullanarak yazılım geliştirirdi. Biz 2 haftada yapıyorsak o bir haftada bitirirdi" demişti. Tabi daha sonra interface,abstract gibi kavramların nesneye yönelik programlamada ne kadar önemli kavramalar olduğunu öğrenince neden o abinin 1 haftada bitirdiğini anladım. :)

Interface ve Abstract kavramları nesneye yönelik programlamanın en temel ve önemli kavramlarından biridir.Önceki yazılarımızda Interface nedir ne zaman kullanılır?, ve Abstract nedir ne zaman kullanılır? ile bu kavramların nerede nasıl kullanıldığına ayrı ayrı konular altında değinmiştik. Eğer okumadıysanız öncelikle eski yazıları okumanızı tavsiye ederim. Aslında iki yazıyıda dikkatlice okuduğunuzda hangi durumda hangisi kullanılabilir diye karar verebilirsiniz.  Bu yazıda da genel bir özet yapıp bu kavramlar hakkında son düşüncelerimi ve kişisel tercihimi yazmak istedim.

Öncelikle daha önceki yazılarda Abstract sınıfların genellikle IS-A(dır,dir) ilişkilerinde,kalıtım(inheritance) özelliğini kullanarak kod tekrarını azaltmak için kullanıldığını söylemiştik. Interface sınıfların ise daha çok CAN-DO(yapabilir..) tarzı ilişkilerde değişen kavramları uygulamadan soyutlamak için kullanıldığını söylemiştik. Birde bu iki kavramın avantaj ve dezavantajlarına bakalım.Sonuçta Abstract bir sınıfın bütün metodlarını abstract yaparak onu da aynı bir interface gibide kullanabiliriz.

Öncelikle bence en büyük fark Abstract sınıfların tekli kalıtım(inheritance ) kullanması Interface sınıfların ise çoklu kalıtıma(multiple inheritance) izin vermesidir.Bildiğiniz gibi bir sınıfı başka bir sınıftan,ya da abstract bir sınıftan türettiğiniz zaman başka bir sınıftan daha türetme imkanınız olmuyor. Fakat interface sınıflarda durum daha farklı. Bir sınıfı istediğiniz kadar interfaceden türetebilirsiniz. Bu bakımdan interface sınıflar abstract sınıflardan oldukça daha esnek diyebiliriz. Fakat interface sınıflara baktığımızda abstract sınıflardan daha yavaş çalıştığı için hız bakımından devavantajı var diyebiliriz.

Şimdi hız mı esneklik mi diye bana soracak olursanız tabiki tercihim esneklikten yana olacaktır. Bu soruyu 2-3 sene önce sorsaydınız önce hız derdim büyük ihtimalle :)

Kendi kişisel tercihim olarak eğer soyutlamak istediğim yapıda ilişki CAN-DO ise ve hiç ortak kod yoksa sadece interface kullanırım. Fakat ortak kod içeriyorsa öncelikle bir interface(dikkat edin yine interface koyarım) koyup ardından ortak kodu kullanan bir abstract sınıf koyup onu o interfaceden türetir ve diğer sınıfları interface sınıfını kullanır hale getiririm.Burada interface i koymasakta olur fakat koymamın sebebi esnekliği arttırması ve özellikle Test Driven Development açısından Mock objelerin oluşturulması için interface kullanan sınıfların test edilmesinin çok daha kolay olması.Mock objelere ayrı bir konu başlığı altında değiniriz fazla uzatmayalım.

Eğer soyutlamak istediğim yapı IS-A ilişkisi ise sadece Abstract sınıf kullanırım. Abstract sınıfların sevmediğim yanı kalıtım(inheritance) diyebilirim.Kalıtım ilişkisi herzaman bağımlılığı(coupling) fazla olan bir ilişkidir. Yani türettiğiniz sınıfa tamamen bağımlı oluyorsunuz. Türettiğiniz sınıftaki herhangi bir değişiklik alt sınıfları etkiliyor. Fakat interface sınıflarda bu tarz bir problem daha az interface içindeki bir metodu değiştirmedikçe hiç bir sınıf bundan etkilenmiyor.Geliştirdiğiniz sınıflar tamamen plug-in mantığı ile interface sınıflar sayesinde hiç problemsiz değiştirilebiliyor. Bu yüzden kalıtıma her zaman şüpheyle yaklaşıyorum. Zaten Object OOP nin insanlar tarafından uzun yıllar kullanıldıktan sonra da aynı fikre varılmış. Kalıtımın bu problemli yapısı görüldüğü için daha sonra kalıtım yerine birleşim(Composition over Inheritance) kullanmak çoğu durumda tercih edilen bir yöntem.OOP için oldukça önemli olan bu konuyuda başka bir yazı konusu olarak ileriye bırakıyorum.

Konu ile ilgili yazıyı yazdığım gün konu ile alakalı çok güzel bir webcast e denk geldim. sizde izleyebilirsiniz. Konu Interface vs Abstract sınıflar. Burada konuşmacı benden daha katı olarak tamamen interface kullanılması gerektiğini savunuyor.Kısmen katılsamda bu şekile katı bir interface kullanımı her zaman doğru olmayabilir. Ayrıca konu ile ilgili daha derin bilgi edinmek için okumaya fırsat bulamadığım Interface Oriented Design kitabını okuyabilirsiniz. Ayrıca Wikide de  kısa bir bilgi verilmiş(Interface Based Programming).

Bu konuda şuanda aklıma gelenler bu kadar.Dediğim gibi konu bir blog yazısına sığmayacak kadar detaylı. En azından biraz ışık tutabilmiştirim. Ne kadar örneği bol tutmaya çalışsamda kendiniz yazmadıkça projelerinizde kullanmadıkta biraz havada kalabilir. O yüzden eller klavyeye diyorum…

6 thoughts on “Interface mi, Abstract mı?

  1. Pingback: Yazılım Mühendisliği » Best Of 2008

  2. yasar

    blogunuz çok güzel fakat temada üst kısımda bir hata veriyor ve sayfa tam olarak açılmıyor.bilginiz olsun istedim.

  3. Pingback: Interface vs. Abstract

  4. Ali Özdemir

    ” Fakat ortak kod içeriyorsa öncelikle bir interface(dikkat edin yine interface koyarım) koyup ardından ortak kodu kullanan bir abstract sınıf koyup onu o interfaceden türetir ve diğer sınıfları interface sınıfını kullanır hale getiririm”

    Burada yazıdığınız cümledeki olay şu şekilde dimi, abstract sınıfı interface den türettiniz sonra diğer sınıfları abstract class dan türettiniz. Doğru mu?

Comments are closed.