Previous
Next

JAVA - Multiple Inheritance (Çoklu Kalıtım)

by Cem Kefeli 30. Ekim 2012 05:39

Daha önce Inheritance(Kalıtım) nedir?Diamond Problem of Multiple Inheritance adresindeki yazımda ve Interfaces(Arayüzler) adresindeki yazımda 'Kalıtım' ve 'Arayüzler' konularından bahsetmiştim. Çoklu kalıtım (Multiple Inheritance) diyorsak arayüzlerden bahsetmemek olmaz tabi. Kalıtım olmadan da 'çoklu' su olmayacağına göre eğer eksikler varsa ilk önce bu iki yazıyı okumanızı öneririm.

Gelelim asıl konuya, Java'da çoklu kalıtım mevzusuna. Aslında daha uzatmadan Java'da çoklu kalıtım yoktur deyip yazıyı bitirebiliriz ama gelin bakalım neden yoktur. Var olanlarda neden ve nasıl vardır?

Sol tarafta bu konu ile ilgili basit ama güzel bir UML diagram var. Class B ve Class C, Class A'dan türeyen yavru sınıflar. Türemenin doğal özelliğini kullanarak doWork isimli metodu da overwrite etmişler. Ne kadar güzel! İşte kalıtım... Fakat bir de Class D var... Olmaz ama diyelim ki Class D öyle birşey yapmış ki hem Class B'den hem de Class C'den türemiş. Yani çoklu kalıtım uygulanmış, türedikten sonra bir de üstüne üstlük doWork method'unu override etmemiş, ki etme zorunluluğu da yok burada. Şimdi ne olacak? doWork methodu son durumda nasıl oluşur? Class B'deki gibi mi yoksa Class C'deki gibi mi? İşte bu bir paradoks, kalıtımda diamond problemi olarak isimlendiriliyor.

C++'da bu işler oluyor ama hangi sınıfın hangi method'unu çağırmak istediğinizi bizzat kendiniz vermeniz gerekmekte. C++ çoklu kalıtıma bu şekilde bir çözüm bulmuş.

C++ Multiple Inheritance  |  Gizle  |  Göster
#include 
using std::cout;
using std::endl;

class ClassA { public: virtual void print() const = 0; // pure virtual }; class ClassB : public ClassA { public: void print() const { cout << "ClassB\n"; } }; class ClassC : public ClassA { public: void print() const { cout << "ClassC\n"; } }; class ClassD : public ClassB , public ClassC { public: void print() const { ClassB::print(); } }; int main() { ClassD Class_D; ClassB Class_B; ClassC Class_C; ClassA *array[3]; array[0] = &Class_D; // ERROR array[1] = &Class_B; array[2] = &Class_C; for( int i=0 ; i<3 ; i++ ) array[i] -> print(); return 0; }

Tekrar Java'ya geri dönecek olursak. C++'da var da neden Java'da bu iş yok diye düşünebilirsiniz ama bu tamamen dilin dizayn aşaması ile ilgili bir durum. Çok kullanılmaması ve yanlış sonuçlara yol açabilmesi, ayrıca tam anlamıyla hiçbir zaman çoklu kalıtım diye birşeyin olmayacak olması Java'yı geliştirenleri böyle bir duruma yöneltmiş. Sonuç olarak Java'da çoklu kalıtımı bir nebze olsun arayüzler ile sağlayabiliyoruz.

JAVA - Interfaces(Arayüzler)

by Cem Kefeli 18. Ekim 2009 10:52

JavaJava'da kalıtımın nasıl gerçekleştirildiğini "Inheritance(Kalıtım) nedir?" başlıklı yazım içerisinde görmüştük. Kalıtım, OOP(Object Oriented Programming) bir dilde olmazsa olmazlardandır ki, uygulama geliştiricilere çok büyük güzellikler sunar. Tüm canlılarda olduğu bigi nesneler arasında da kalıtım ilişkisi kurulur ve yeni yeni türler tanımlanmasını mümkün kılar. Bir nesne tanımlarsınız, sonra bu nesneden başka bir nesne daha türetebilirsiniz. Fakat ya iki ya da daha çok nesnenin bir araya gelip bir nesne oluşturmasını isterseniz ne olacaktır? İşte burada durum karışıktır! Çünkü java çoklu kalıtmı desteklemez. Bir nesneyi yalnızca bir tane nesneden türetebilirsiniz. Bu aşamada imdadımıza Interfaces(Arayüzler) yetişir ve her ne kadar tam anlamıyla çoklu kalıtım olmasa da buna benzer bir davranışı bizlere sunar.

  • Arayüzler içerisinde yalnızca Abstract(Soyut) metodlar ve sabitler(constants) bulundurabilirler, gövdeli metodlar barındıramazlar. Soyut metodları ve sınıfları incelerken de soyut sınıfların bir birleştirici rol oynadıklarını, soyut sınıflardan türeyen sınıflara adete bir kılavuz gibi yol gösterdiğinden bahsetmiştik. Fakat soyut sınıflar gövdeli metodlar yani iş yapabilen metodlar da barındırabiliyorlardı.
  • Ayrıca bir sınıfın birden fazla soyut sınıftan türemesi de söz konusu değildi.
  • Hem soyut sınıflarda hem de arayüzlerde ortak olan bir nokta ise, soyut sınıflarda abstract olarak tanımlanan ve arayüzlerde tanımlanan her metodun bu soyut sınıf ve arayüzlerden türeyen tüm sınıflarca override edilmesi gerekliliğidir. Bu arada şunu söylemek gerekir ki arayüzler içerisindeki metod tanımlamalarında soyut sınıflarda kullandığımız gibi abstract anahtar sözcüğünü kullanamıyoruz. Nedeni ise arayüzlerin içerisindeki tüm metodların zaten abstract olarak değerlendirilmesidir. Dilin mimarisini oluşturanlar ayrıca bir daha abstract tanımlama yapılmasını gerekli görmemişler. Eğer yazarsanız hata mesajı ile karşılaşırsınız.
  • Bir diğer nokta ise arayüz içerisinde yapılan tüm metod tanımlamaları için bir erişim belirleyicisinin kullanılamayacağıdır. Varsayılan erişim belirteci olarak public seçilmiştir ve sizin bunu değiştirme şansınız da yoktur. Eğer bir metodun erişim belirleyicisini değiştirip örneğin private gibi bir erişim belirteci verebilseydiniz türeyen sınıflarda bu metodları override edebilmek imkansız olacaktır. Bu da arayüzler içerisindeki tüm metod tanımlamaları türeyen sınıflarda override edilmelidir ilkesi ile çelişecektir. Tabi ki metodların dönüş bildirim değerlerinin olmayacağı anlamına gelmemektedir ve bu ikisi birbirinden ayrı şeylerdir.Arayüzler içerisinde metodlar haricinde global alanlar da tanımlayabildiğimizi söylemiştik. Erişim belirleyicisi olarak bu alanlarlar da yine public olarak değerlendirmektedir. Bunu da sizin değiştirme şansınız yoktur. Ayrıca alanlara static ve final erişim belirteci de eklenmiştir, metodlardan farklı olarak. Tabiki bunlar arayüzler içerisinde birebir olrak yazan şeyler değildir. Yazılmasa dahi varsayılan olarak kabul görmektedirler.
  • Soyut sınıflardan başka soyut sınıflar türetebiliyorduk. Bu böyle arda arda devam edip gitmekteydi. Yine hatırlarsanız türeyen soyut sınıflarda, türedikleri soyut sınıf içerisinde yer alan soyut metodları override etme gibi bir zorunluluk da yoktu. Aynısı arayüzler için de geçerlidir. Arayüzler de başka arayüzlerden türeyebilmektedir ve bu özellik de arayüzler arasında da kalıtım ilişkisinin kurulabilmesini sağlamaktadır.

Bu birkaç önemli noktanın üzerinde durduktan sonra şimdi biraz daha uygulamaya dönük birşeyler yapabiliriz artık. Uygulama demişken Java'da arayüzler interface anahtar sözcüğü ile tanımlanmakta ve implements anahtar sözcüğü ile de uygulanmaktadır. Aşağıdaki örnekte yukarıda bahsettiğimiz bu birkaç özellik ile ilgili bir uygulama vermekteyim.Fazlası...

Hakkımda...

Cem KEFELİ

Electronics and
Telecommunication Eng.
devamı...


Son yapılan yorumlar...

Comment RSS

Yasal bir uyarı...

Disclaimer"Bu web sitesinde görmüş olduğunuz bilgilerin, dokümanların ve diğer materyallerin kullanılmasından doğabilecek hiç bir sorumluluktan site sahibi sorumlu tutulamaz. Web sitesi içerisinde yer alan yazılar, yorumlar, resimler ve diğer tüm içerikler yalnızca sahibinin görüşünü yansıtmakta olup içeriğin sahibi kişilerin çalıştığı kurumları bağlayıcı hiç bir nitelik taşımamaktadır. Yapılan tüm alıntılar mutlaka kaynak gösterilerek verilmeye çalışılmaktadır. Web sitesi içerisinde bulunan ilgili materyaller, ilgili yasal kurumlar tarafından uygun görülmemesi durumda kaldırılacaktır."
General