Previous
Next

JAVA - Hidden Inheritance (Gizli Kalıtım)

by Cem Kefeli 31. Ekim 2012 01:34

JavaAslında buradaki linki takip ederseniz birkaç başlık halinde Java'da kalıtımı ilgilendiren birçok bilgiye ulaşabilirsiniz. Gizli kalıtım da bu yazıların birisi içerisinde yer bulabilirdi fakat hem zamanında yazmayı atlamışım hem de sonradan bu konuyu farklı bir başlık olarak ele almanın daha uygun olacağını düşündüm.

Gizli kalıtım, hem kalıtımla ilgili tabiki hem de aslında Java'da sınıflar ve nesnelerin doğal işleyişi ve dil yapısı ile ilgili de mantıksal bilgiler veriyor. Nasıl?

Hidden inheritance example  |  Gizle  |  Göster
public class HiddenEx {
    // Hic bir sey yok!
}
public static void main(String[] args) {
    HiddenEx Class1 = new HiddenEx(); 
    HiddenEx Class2 = new HiddenEx(); 
    HiddenEx Class3 = Class2;
    System.out.println("Class1.toString(): " + Class1);
    System.out.println("Class2.equals(Class1): "+Class2.equals(Class1));
    System.out.println("Class2.equals(Class3): "+Class2.equals(Class3));
    System.out.println("Class2.hashCode(): " + Class1.hashCode());
}
Class1.toString(): HiddenEx@addbf1
Class2.equals(Class1): false
Class2.equals(Class3): true
Class2.hashCode(): 11394033

Şimdi bu örneğe bakınca ilk önce şu soruları sormanız gerekir. "İyi de ben HiddenEx isimli sınıfta ne toString isminde bir method tanımladım ne equals ne de hashCode? Nereden geldi peki bu methodlar? Tanımlamadığım bir methodu nasıl kullanabildim?"

Hidden inheritance (Object class)  |  Gizle  |  Göster
public class HiddenEx extends Object {
    // Hic bir sey yok!
}

Bu soruların tümünün cevabı da yukarıdaki bir numaralı boyalı satırda saklı. Çünkü Java'da tüm nesneler gizli olarak Object sınıfından türer. Object tüm sınıfların atasıdır diyebiliriz, bu Java'nın sınıf yapısının kurgusudur. Siz bir sınıf oluşturduğunuzda bu sınıf aslında gizli bir şekilde Object sınıfından extend edilir. Dolayısı ile yukarıdaki saydığım üç adet method zaten Object sınıfının içerisinde tanımlı olduğu için HiddenEx sınıfı içerisinde kullanılabildi. Yalnızca bu üç method değil başka methodlar da var bu şekilde... İşte gizli kalıtım bu şekilde ifade edilebiliyor...

Peki Bir sınıf daha düşünün bu sınıf da HiddenEx sınıfından türesin ve adı da HiddenEx2 olsun. HiddenEx2 hem Object hem de HiddenEx sınıflarından aynı anda mı türeyecektir? Cevap hayır... Çünkü Java'da multiple inheritance (Çoklu kalıtım) yoktur. HiddenEx2 sınıfı HiddenEx sınıfından türer, HiddenEx ise Object sınıfından türer.

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 - Inheritance(Kalıtım) nedir?

by Cem Kefeli 28. Kasım 2010 03:44

JavaDaha önce nesneye yönelik bir dilin olmazsa olmazlarından birisi olan kalıtım(Inheritance) konusundan "Polymorphism nedir?" başlıklı yazım içerisinde bahsetmiştim. Çünkü çok biçimlilik(Polymorphism) kalıtım ile oldukça iç içe geçmiş ve kalıtımın yok açtığı doğal sonuçların bir uygulaması olarak göze çarpmaktadır. Dolayısı ile kalıtımın olmadığı bir ortamda çok biçimlilikten söz etmek olanaksızdır.

OOP(Object Oriented Programming) diyorsak nesnelerden bahsediyoruz demektir. Herşey nesne olarak düşünülebilir. Nesneler ise birbirlerinden türeyebilmektedir. Örneğin bir ana sınıf düşünün aklınızda, bir de bu ana sınıfın yavrucuklarını düşünün. Yavrucukları diyorum ama, bunu yavru sınıflar daha küçüktür, daha az öğe içerir gibi düşünmeyin sakın. Tam tersine bu yavrucuklar daha gelişkin olabilirler. Annelerinin tüm özelliklerine sahip olurlar da, hatta bir de annelerinden farklı başka özellikler de içerebilirler. Bu yavrucukların da yavrucukları olabilir. Bu böyle devam eder gider. Hemen aşağıda kalıtımın olduğu bir ortamdan ve bunun uygulamalarından bahsetmeye çalışacağım.

Sağ tarftaki UML diagramında bir kalıtım yapısı bulunmakta. TASIT ana sınıfı(Base class) BenNeyim isminde bir fonksiyon ve integer türünde Deger1, Deger2, Deger3 isimli üç farklı değişken bulundurmaktadır. TASIT sınıfına ait BenNeyim isimli fonksiyon kendisinin bir taşıt olduğunu belirten log yazdırmaktadır. MOTORLUTASIT ve MOTORSUZTASIT sınıfları ise TASIT ana sınıfından türemekte ve Deger4 isimli integer türünden bir değişken bulundurmaktadır. Java dilinde türetme işlemleri extends anahtar sözcüğü ile yapılmaktadır. Deger4 ise ana sınıfta bulunmayan ve türeyen sınıflar(Derived class) ile birlikte gelen bir değişkendir. Peki ya ana sınıftaki Deger1, Deger2, Deger3 isimli değişkenlere ne oldu? Acaba yeni türeyen MOTORLUTASIT ve MOTORSUZTASIT sınıfları içerisinden bu değişkenlere erişip kontrol edebilir miyim ki? Bu sorularımıza ve merakımıza biraz daha gem vuruyor ve şimdilik aklımızın bir köşesine yazarak az sonra öğrenmek için bir kenera bırakıyoruz. Dikkat edilirse yeni türettiğimiz Inheritance UML sınıflar ile birlikte güzel bir ayrıntı gözümüze çarpar oldu. Artık " Türeyen her sınıf, ana sınıfı içerir" diyebiliriz kolay bir şekilde. Yani bir bakıma her MOTORLUTASIT ve MOTORSUZTASIT aslında birer TASIT'tır demek oluyor bu. İşte aralarında bu şekilde ilişki kurulabilen her ortamda kalıtımdan söz etmek mümkündür. Bu bahsettiğimiz 'IS A' ilişkisi olarak bilinmektedir. ("MOTORLUTASIT IS A TASIT" == MOTORLUTASIT bir TASIT'tır.) Yine bu türemiş sınıflara ait BenNeyim fonksiyonu da sınıfın ne olduğunu yazdırmaktadır. TAKSI ve OTOBUS, MOTORLUTASIT sınıfından türeyen sınıflardır. Fakat bu sınıfların kendisine özgü başka değişkenleri oluşturulmamıştır. Oluşturulma zorunluluğu da yoktur zaten. Ana sınıf içerisinde soyut(Abstract) olarak belirtilmedikçe override edilmesine gerek yoktur. Fakat ana sınıf içerisinde soyut olarak tanımlanmış bir öğenin alt sınıf içerisinde mutlaka override edilme zorunluluğu bulunmaktadır. Yazının ilerleyen bölümlerinde bu konuları daha detaylı inceleyeceğiz. Yalnızca MOTORLUTASIT sınıfına da kalıtım yolu ile geçen BenNeyim fonksiyonu iptal edilmiş(Override) ve kendisine özgü bir içerik oluşturulmuştur. Aynı şeyleri OTOBUS sınıfı için de söylemek mümkündür. BISIKLET sınıfı ise MOTORSUZTASIT sınıfından türemektedir ve tıpkı TAKSI ve OTOBUS gibi kendisine özgü yeni değişkenleri bulunmamaktadır. TAKSI, OTOBUS ve BISIKLET sınıflarının üçüde kalıtım ile kendilerine geçen BenNeyim fonksiyonu içerisine kendisinin ne olduğunu yazdıran yeni kod blokları eklemişlerdir. Yukarıda sorduğumuz sorunun bi benzeri de burda söz konusudur. MOTORLUTASIT ve MOTORSUZTASIT türemiş sınıfları içerisinde yeni oluşturulan Deger4 isimli değişkeni acaba TAKSI, OTOBUS ve BISIKLET sınıfları içerisinde kullanabilir miyim? En alt sınıf olan TASIT sınıfı içerisinde bu değişkenin olamamasına rağmen. İşte şimdi yavaş yavaş bu UML diagramına göre hazırlanmış ve bazı eklentiler yapılmış aşağıdaki kod bloğuna bakma ve sorularımızın cevabını alma vakti geldi. Fazlası...

JAVA - Abstract(Soyut) sınıflar ve metodlar

by Cem Kefeli 27. Mayıs 2010 04:00

JavaJava programlama dili için soyutlama demek; birilerini soyut tanımlanan her şeyi override etmeye mecbur kılmak demektir dersem sanırım çok da mantıksız olmaz. Biraz karışık mı oldu? O halde devam edelim.... Java'da soyutlama sınıflara ve metodlara uygulanabilmektedir. Aslında buraya kadar söylediğim herşey C# için de aynı. Soyutlama bir konsepttir aslında, dilden dile pek bir farklılık içermez. Soyut tanımlanan hiçbirşey kendi başlarına işe yaramazlar, iş görmezler. Yalnızca bir yol gösterici bir kılavuzdurlar aslında. İçerikleri de yoktur soyut metodların. Soyutlama, kalıtım ile tamamen ilgilidir. Zira az önce bahsettiğim bu yol gösterme ve kılavuzluk türeyen yeni nesnelere yapılmaktadır.

Şimdi biraz daha derinlere dalalım. Kalıtım ve overriding ile ilgili detaylı bir inceleme "Inheritance(Kalıtım) nedir?" başlıklı yazım içerisinde yapmıştım. Soyutlama da kalıtım ve overriding ile çok iç içe olduğu için eksiği olduğunu düşünenler ilk önce burayı tıklayarak gerekli alt yapıyı kurabilirler. Abstract Classes UML Şimdi asıl konumuza geri dönecek olursak, biliyoruz ki ana sınıftan türeyen yavru sınıflar içerisinde ana sınıflara ait metodları override edebiliyorduk. Fakat bu tamamen bizim isteğimize kalmış bir durumdur. Yani siz eğer override etmek isterseniz edersiniz, eğer override etmek istemezseniz ya da buna gerek duymuyorsanız kimse size neden override etmedin diye sormaz. Override etmemeniz derleme zamanında(compile time) ya da çalışma zamanında(run time) herhangi bir hataya da sebebiyet vermez. Pekiala biz eğer bir metodun, metodun içinde bulunduğu sınıftan türeyen tüm alt sınıflarda override edilmesini istiyorsak ne yapmalıyız? İşte soyutlama tam olarak burada karşımıza çıkmaktadır. Yani yazdığımız sınıftan türeyen tüm yavrucularda belirttiğimiz sınıfltarın override edilmesini ve yeniden bir içerik oluşturulmasını zorunlu kılabiliyoruz bir metodu abstract(soyut) tanımlayarak. Bir metodun soyut olarak tanımlanması o metodun bulunduğu sınıftan türeyen tüm sınıflarda override edileceğini garanti altına alır. Peki bu bizim için neden gereklidir? bırakalım da ona yeni sınıfı türeten adam karar versin diyemez miyiz? Diyemeyiz... Şöyle ki; tanımladığımız soyut metod alt üyelerde de mutlaka bulunması gereken fakat ana sınıf için birşey ifade etmeyen bir yapıya sahip olabilir. Yani bu cümleden sonra şu kanıya varabiliriz. Soyut metodlar ana sınıflar için anlamsızdır ve birşey ifade etmezler, asıl anlamlarını ise yavru sınıflar içerisinde kazanırlar. Şimdi bir örnek yaparak bu dediklerimizi biraz daha somutlaştıralım. Sağ taraftaki şekilde örneğe ait UML diagramını bulabilirsiniz.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