Merhaba Arkadaslar,
Bu yazimda Reference Variable Casting / referans degisken donusumu konusundan bahsedecegim.
Daha once de belirttigim gibi , Java ‘da 2 tip degisken vardir
- primitive / ilkel( char,boolean,byte,short, int,long,double ve float)
- reference/referans
Bir reference variable/referans degisken bir objeye erismek/access icin kullanilir. Reference Variable belirli bir tipte tanimlanir ve tanimlanan bu tip degistirilemez.
Bir reference variable/referans degisken , tanimlandigi tipteki objeye veya tanimlandigi tipin alttipi/subtype turundeki objelere ulasmak icin kullanilabilir. Fakat ust tipteki bir objeye erismek icin kullanilamazlar.
CastTest.java
class Animal { void eat() { System.out.println("Animal Eat"); } } class Dog extends Animal { @Override void eat() { System.out.println("Dog Eat"); } void bark() { System.out.println("Dog Bark"); } } public class CastTest { public static void main(String[] args) { Animal[] animal = { new Animal(), new Dog(), new Animal() }; for(Animal a: animal){ a.eat(); if(a instanceof Dog) { //a.bark(); ((Dog) a).bark(); } } } }
Ornegimizi inceleyecek olursak , Animal sinimizda eat() metodu bulunmaktadir, Dog sinifinda ise eat() metodunu override ediyoruz ve bark() metodunu ekliyoruz.
CastTest sinifimizda Animal turnude bir dizimiz var ve 3 tane eleman ekliyoruz. Burada dikkat ederseniz Animal dizimize Dog objesi ekleyebiliyoruz, cunku Dog sinifi Animal sinifini kalitmaktadir.Boylece, Dog IS-A Animal sarti saglanmaktadir.
if kontrolu icerisinde a’nin Dog turunde olup olmadigini kontrol ediyoruz, bu durumda ( new Dog() olarak ekledigimiz ikinci eleman sarti saglayacaktir ).
Burada Dog sinifinda yer alan bark() metodunu cagirabilmek icin reference variable/ referans degiskenimizi cast islemine tabi tutuyoruz.
Burada oldugu gibi , kalitim agacinda ust siniftaki bir sinifi alt sinifa cast etme islemine downcast denilir.
Simdi de ilginc bir noktayi inceleyelim ;
CastTest2.java
class Animal { } class Dog extends Animal { } public class CastTest2 { public static void main(String[] args) { Animal animal = new Animal(); Dog d = (Dog) animal; } }
Bu kod sorunsuzca compile edilir /derlenir. Fakat calisma zamaninda soyle bir hata ile karsilasilir ;
java.lang.ClassCastException
Compiler burada derleme zamaninda hata vermemektedir, downcast in sorunsuz bir sekilde calisabilme ihtimaline karsi calisma zamanina kadar sorun cikartmaz.
Animal animal = new Dog();
seklinde olursa downcast sorunsuz bir sekilde gerceklesir.
Fakat soyle bir casting islemine derleme zamaninda dahi izin vermez ;
String s= (String)animal;
Animal ve String kalitim hiyerarsisinde farkli yerlerde bulunmaktadir ve burada casting islemi yapilmasi mumkun degildir.
downcasting oldugu gibi bir de upcasting islemi vardir ;
class Animal { } class Dog extends Animal { } public class CastTest2 { public static void main(String[] args) { Animal animal = new Dog(); Dog d = (Dog) animal; // String s= (String)animal; Dog d2 = new Dog(); Animal a1 = d2; Animal a2 = (Animal) d2; } }
Dog turunde bir obje olusturduk ve d2 reference variable / referans degiskenimizi Animal turundeki reference variable / referans degikenine atiyoruz. Burada oldugu gibi kalitim hiyerarsisinde ust sinifa dogru cast etme islemine upcasting denilmektedir.
Animal a1=d2; de oldugu gibi imlicit /kapali/ortulu veya Animal a2=(Animal)d2; de oldugu gibi explicit /acik olarak cast etme islemi yapilabilir.
Dog IS-A Animal ifadesi gecerlidir , cunku Dog , Animal sinifini kalittigi icin sorunsuz bir sekilde casting yapilabilir.