Abstract class nedir ve Python’da nasıl kullanılır?
Abstract classları türkçeleştirerek anlatmaktan ziyade, direkt olarak terminoloji ile anlatmayı tercih ediyorum. Bu sayede abstract methodu ezberlemek yerine hissetmeye çalışacağız.
Abstract classlar içerisinde bir veya daha fazla abstract method tanımlaması barındıran classlardır. Abstract method nedir? Abstract method dediğimiz şey ise tanımlı methodların sadece ismi olup içeriği olmaması durumudur. Örneğin okula_git adında bir methodu isim olarak yazıyoruz ama okula nasıl gidileceğini yani fonksiyonun gövdesini tanımlamıyoruz. Peki ama neden? Tabi ki de daha esnek sistemler yapabilmek için. Örneğin bir uygulamada ödeme sistemi yapılması gerektiğini varsayalım bir gün iyzico kullanırken öteki gün Stripe’a geçiş yaptığımızda ne olacak? Komple bütün modülü silip tabi ki baştan yazmayacağız. Bütün sistemi abstract classların subclassları ile oluşturacağız. Örneğin bizim abstract classımızın içerisinde ödeme_yap adında fonksiyon olsun ve bunu biz tanımlamayalım. Bu abstract class iyzico backendi tarafından miras alındığında içerisinde ödeme_yap fonksiyonunu tanımlamak zorunda olacaktır. Yarın bir gün birden Stripe alt yapısına geçersek bu durumda da yine stripe classı bizim bu abstract classını miras almalıdır ki, abstract classın içerisinde ki ödeme_yap fonksiyonunu ezip implemente etmek zorunda kalsın. Bu sayede aslında bir düzen oturtmuş oluyoruz. Hangi alt yapı kullanılırsa kullanılsın diyoruz ki siz ödeme_yap fonksiyonunu bu isimde kullanmalısınız ama içeriğiniz değişebilir. Ama sonuç olarak hangi sistem gelirse gelsin ne olursa olsun fonksiyon adı sabit kalmış olacaktır.
Buradan anladığımız şu aslında, Abstract classlar kendi başına kullanılamazlar içerisinde abstract method yani tanımlanıp implemente edilmemiş methodları barındırırlar. Abstract classlar subclasslara ihtiyaç duyarlar yani miras alınmalıdır hemen bir örnek yapalım.
Python bizlere abstract classları sunmaz ama ABC modülü sayesinde (Abstract Base Classes) abstract classlar tanımlayabiliriz.
Aşağıda ki gibi bir Abstract Class tanımladığımızı varsayalım. Bu bizim ödeme sistemimiz için örnek bir alt yapı oluşturacak. Bu classın tüm alt classları otomatik olarak “make_payment” fonksiyonunu tanımlamak zorunda kalacaklar. Biz iyzicoda kullansak, iyzicoya göre “make_payment” fonksiyonunu tanımlamalıyız. Eğer yeni bir alt yapı ile devam edeceksek örneğin Stripe bu seferde stripea göre “make_payment” fonksiyonunu tanımlamalıyız. Sonuç olarak varacağımız nokta şu bizim sistemimizde hangi alt yapı kullanılırsa kullanılsın “make_payment” bulunmak zorundadır. Tabi ki ben içerisine bir tane fonksiyon tanımladığım için buna ne gerek var? Ben zaten bir fonksiyonu aklımda tutabilirim diyebilirsiniz. Öyle zamanlar gelecek ki 200 tane ayrı fonksiyonu aklınızda tutmak zorunda kalabilirsiniz. Abstract Class sayesinde bir temel oluşturabiliriz.
Temel payment classımız oluştuğuna göre artık x servisini kullanarak bir alt yapı yazabiliriz. Bizim sistemimizde sadece “make_payment” işlevi olduğunu varsayarsak. Aşağıda ki gibi AbstractPaymentClassının sub classını üretebiliriz.
NOT: XServicePayment classını olutururken AbstractPaymentClass üzerinden miras alıp make_payment fonksiyonunu implemente etmeseydik. Bu classtan yeni obje ürettiğimizde hata alırdık. Soyut sınıfları miras olarak aldığınızda içerisinde ki implemente edilmemiş olan tüm fonksiyonları implemente etmek zorundayız!