Pure Java – 82 Nested Class – Anonymous Inner Class

Merhaba Arkadaslar,
Bu yaziya kadar regular inner class ve method local inner class yapilarini inceledik.Burada Anonymous Inner Class konusunu inceleyecegiz.

Anonymous Class’lar kodunuzun daha kisa olmasini saglar. Sinif tanimlamanizi ve ilgili siniftan bir ornek/instance olusturmanizi ayni anda yapabilmemizi saglar. Anonymous Inner Class‘larin isimleri yoktur.

Ornegimiz ile baslayalim ;

class Keyboard {
	public void write() {
		System.out.println("Keyboard Write");
	}
}

public class Computer {

	Keyboard keyboard = new Keyboard() {
		@Override
		public void write() {
			System.out.println("Anonymous Write");
		}
	}; // noktali virgulu unutmayalim!

	Keyboard keyboard2 = new Keyboard();

	public static void main(String[] args) {
		Computer com = new Computer();
		com.keyboard.write();

		com.keyboard2.write();
	}

}

Anonymous inner class yapisinda yeni bir obje olusturmaktayiz. Burada objenin tipi Keyboard degildir , objenin tipi Keyboard sinifinin anonymous subclass/altsinif tipindedir.

	Keyboard keyboard = new Keyboard() {
		@Override
		public void write() {
			System.out.println("Anonymous Write");
		}
	};

Unutmayalim ; Java’da anonymous inner class ,subclass/alt siniftir !

class Engine {

	public void speedUp() {
		System.out.println("Engine speedUp");
	}
}

public class Car {

	Engine engine = new Engine() {

		@Override
		public void speedUp() {
			System.out.println("Anonymous speedUp");
		}

		public void drift() {

		}

	};

	public static void main(String[] args) {
		Car car = new Car();
		car.engine.speedUp();

		// car.engine.drift();
		// derleme hatasi
	}
}

Burada “engine” referans degiskeni Engine sinifi tipindedir. Objenin tipi ise Engine sinifinin , Anonymous alt sinifi tipindedir.
Hatirlayacagimiz gibi , Java’da bir referans degisken kendisi veya alt sinif tipinde objeye referansta bulunabilir.
Referans degiskenin ait oldugu Engine sinifinda drift isimli metot bulunmamaktadir Bu nedenle drift metodunu cagiramayiz !
speedUp metodunun override hali cagrilacaktir , cunku objenin tipi alt sinif tipindedir.

Anonymous yapisinda class/sinif kullanabildigimiz gibi abstract class/sinif veya interface/arabirim de kullanabiliriz.

interface MyInterface {
	public void test();
}

abstract class AbstractClass {
	public abstract void test2();
}

public class AnonymousTest {

	public static void main(String[] args) {
		MyInterface myInterface = new MyInterface() {
			@Override
			public void test() {
				System.out.println("Anonymous test");
			}
		};

		myInterface.test();

		AbstractClass abs = new AbstractClass() {

			@Override
			public void test2() {
				System.out.println("Anonymous test2");
			}
		};
		
		abs.test2();
	}
}

Burada interface tipinde bir obje olusturmuyoruz! MyInterface arabirimini uygulayan(implements) anonymous sinif tipinde bir obje olusturuyoruz. Burada anonymous implementer class sadece bir arabirimi uygulayabilir ve anoymous subclass ya bir ilgili sinifi kalitabilir(extends) ya da ilgili arabirimi uygulayabilir(extends).

  • Bir anonymous class , outer class in uyelerine erisebilir.(methods & variable)
class Anonymous {
	void test() {
	}
}

public class AnonymousTest2 {

	private String privateVariable = "private variable";

	private void outerMethod() {
		System.out.println("Outer method");
	}

	Anonymous anonymous = new Anonymous() {
		void test() {
			System.out.println(privateVariable);
			outerMethod();
		}
	};

	public static void main(String[] args) {
		AnonymousTest2 anonymousTest2 = new AnonymousTest2();
		anonymousTest2.anonymous.test();
	}

}
  • Bir anonymous class eger metot icerisinde tanimlanmissa, metot icerisindeki local degiskenlere ulasamaz. Eger local degisken final tanimliysa bu durumda ulasim saglanabilir.
class Anonymous {
	void test() {
	}
}

public class AnonymousTest3 {

	private void outerMethod() {
		 String localVariable="I am local variable";
		 final String finalLocalVariable="I am final local variable";
		Anonymous anonymous = new Anonymous() {
			void test() {
				//System.out.println(localVariable); //derleme hatasi
				System.out.println(finalLocalVariable);
			}
		};
	}

}
  • Shadowing durumu Anonymous class’lar icin de ortaya cikabilir.
class Anonymous {
	void test() {
	}
}

public class AnonymousTest4 {

	private String shadowing = "Shadowing Outer";

	private void outerMethod() {

		Anonymous anonymous = new Anonymous() {
			void test() {
				String shadowing = "Shadowing Anonymous";
				System.out.println(shadowing);
				System.out.println(AnonymousTest4.this.shadowing);
			}
		};
	}

}

Anonymous class icerisinde static degisken sadece final olarak tanimlanabilir. static metot ise final olsa da tanimlanamaz.

class Anonymous {
	void test() {
	}
}

public class AnonymousTest5 {

	private String shadowing = "Shadowing Outer";

	Anonymous anonymous = new Anonymous() {
		// static String staticVariable = "compile error";

		final static String finalStaticVariable = "i am final static variable";

		void test() {
			String shadowing = "Shadowing Anonymous";
			System.out.println(shadowing);
			System.out.println(AnonymousTest5.this.shadowing);
		}

		// static void compileError() {}
		// final static void compileErrorToo() {}

	};

}

Buraya kadar inceledigimiz Anonymous Inner Class’lar, Plain-Old Anonymous Inner Class olarak isimlendirilir. Bir diger kullanim sekli olarak Argument-Defined Anonymous Inner Class olarak adlandirilan yapi vardir.

interface MyInterface {
	void test();
}

class MyClass {
	void doStuff(MyInterface iface) {
		System.out.println("MyClass doStuff");
	}
}

public class ArgumentDefinedAnonymous {

	public static void main(String[] args) {
		MyClass myClass = new MyClass();

		myClass.doStuff(new MyInterface() {

			@Override
			public void test() {
			}// test metodu
		}// anonymous inner class
		); //doStuff metodu
	}
}

doStuff metodu MyInterface tipinde bir parametre almaktadir. new anahtar kelimesi ile interface objesi olusturamayiz.
Bu durumda Argument Defined Anonymous Class kullanabiliriz. doStuff metodunu cagirirken bu yapiyi kullanabiliriz.

Yazimi burada sonlandiriyorum.
Herkese Bol Javali Gunler dilerim.
Be an oracle man , import java.*;
Levent Erguder
OCP, Java SE 6 Programmer
OCE, Java EE 6 Web Component Developer

Print Friendly, PDF & Email

Leave a Reply

Your email address will not be published. Required fields are marked *