20 Static Variables and Methods

Merhaba Arkadaslar,
Bu yazimda Javada static anahtar kelimesinden bahsedecegim ve metotlar ve degisken icin kullanimi inceleyecegiz.

Oncelikle belirtmem gerekir ki static metot degiskeni bol miktarda tanimlamak object oriented yapisinin temeline dinamit koymaktir

Gerektigi ozel zamanlarda kullanmak gerekir. Dusunelim bize tum objelerden bagimsiz olarak gerekli bir sayac gerekmektedir bu sayaci nasil tutabiliriz. Boyle durumlarda static bir degisken cozum saglayabilir.

static degiskenler ve metotlar sinifa aittirler. Ayri bir instance/ornek/nesne yaratmadan kullanabiliriz. static bir degiskenin tek bir kopyasi bulunur ve tum instance/ornek/nesneler icin bu tek deger paylasilir.

Su basit ornegimizi inceleyelim , static bir int degisken tanimladik ve 0 a atadik , yapilandirici icerisinde degerini 1 arttirdik.

public class CounterEx {

	static int count =0;

	CounterEx() {
		count++;
	}

	public static void main(String[] args) {
		new CounterEx();
		new CounterEx();
		new CounterEx();
		System.out.println("counter value:"+count); //3
	}
}

count degerine 0 atamasi islemi CounterEx sinifi JVM ( Java Virtual Machine)  ‘e herhangi bir CounterEx instance/nesnesi yaratilmadan once gerceklesir. Ek olarak static degiskenler de instance degiskenler gibi deger atanmadigi durumda otomatik deger alirlar. Bildigimiz gibi int bir degisken icin otomatik deger 0 dir.

Peki static degisken degilde instance/ornek/obje degiskeni kullansaydik

public class CounterEx {

	int count = 0;

	CounterEx() {
		count++;
	}

	public static void main(String[] args) {
		new CounterEx();
		new CounterEx();
		new CounterEx();
		System.out.println("counter value:" + count); // compile error
	}
}

bu durumda derleme hatasi aliriz. Bu Javaya yeni baslayan arkadaslarin basina cok fazla gelen bir hata turudur.

Cannot make a static reference to the non-static field count

Peki neden boyle bir sorun oluyor ? JVM hangi CounterEx objesinin , count degiskenine ulasacagini bilmiyor. main() metodunun kendisi static metot ve bu nedenle static bir metot icerisinden static olmayan degiskene ulasim saglayamayayiz.

A static method cant access a non static(instance) variable or method , because there is no instance! static bir metottan static olmayan bir metoda da ulasamayiz ;

public class CounterEx {

	int count = 0;

	CounterEx() {
		count++;
	}

	void method() {
		System.out.println(count); // OK
	}

	public static void main(String[] args) {
		new CounterEx();
		new CounterEx();
		new CounterEx();
		System.out.println("counter value:" + count); // 3
		method();  // compile error

	}
}

Su kodu inceleyelim ;

class Counter {
	private int count;

	public int getCount() {
		return count;
	}

	public void setCount(int count) {
		this.count = count;
	}

	static int staticVar;
}

public class Test {
	public static void main(String[] args) {
		Counter c = new Counter();
		c.setCount(10);

		System.out.println(c.getCount());

		System.out.println(Counter.staticVar);
	}
}

Burada ise c Counter turunde bir referans degiskenidir ve bir Counter objesini referans etmektedir. Bu referans ettigi objenin counter degiskenine 10 atiyoruz ve sonrasinda bu degeri getCount metodunu cagirarak aliyoruz. Burada count degiskeni obje ile baglantilidir.

static degiskene , basina sinif ismini yazarak ulasabiliriz. Counter.staticVar da oldugu gibi.

Burada inceledigimiz ana kurallari tekrar soylecek olursak ;

int size =10;
static void doMore(){
	int x =size; //static bir metottan non-static bir degiskene erismek 
                      // derleme hatasina yol acar.

// static method cannot access an instance (non-static) variable
}

void go();
static void doMore(){
go(); // static metottan non-static bir metoda erismek derleme 
      //hatasina yol acar
// static method cannot access a non-static method
}

static int count;

static void foo(){ }
static void bar() {
foo(); 
int x= count;       

// static metottan static degiskenlere ve metotlara erisim saglanabilir.
// static method can access a static method or variable.
}

Bir kac trick bilgi daha verelim, static metotlar override edilemezler, redefined / tekrar tanimlanirlar.

Oncelikle override isleminin oldugu ornegi inceleyelim , yani metotlarimizin static olmadigi

class SuperClass {
	 void foo() {
		System.out.println("i am SuperClass");
	}

}

class SubClass extends SuperClass {
	 void foo() {
		System.out.println("I am SubClass");
	}
}

public class Test {
	public static void main(String[] args) {
		SuperClass sc1 = new SuperClass();
		SubClass sc2 = new SubClass();
		SuperClass sc3 = new SubClass();

		sc1.foo();  // i am SuperClass
		sc2.foo();  // I am SubClass
		sc3.foo();  // I am SubClass

	}
}

Ciktiyi inceleyecek olursak supriz bir durum olmadi bildigimiz override kurallari isledi. Peki ya foo metodumuz static olursa ?

class SuperClass {
	static void foo() {
		System.out.println("i am SuperClass");
	}

}

class SubClass extends SuperClass {
	static void foo() {
		System.out.println("I am SubClass");
	}
}

public class Test {
	public static void main(String[] args) {
		SuperClass sc1 = new SuperClass();
		SubClass sc2 = new SubClass();
		SuperClass sc3 = new SubClass();

		sc1.foo(); // i am SuperClass
		sc2.foo(); // i am SubClass
		sc3.foo(); // i am SuperClass
	}
}

Ciktiyi inceleyecek olursak , override islemi gerceklesmedi ve sc3 referans degiskeni SuperClass a ait olan foo metodunu cagirdi, oysa override oldugunda SubClass sinifina ait olan foo metodu cagrilir. Ek bir detay  olarak  override islemi olmasa da SubClass sinifinda tanimladigimiz foo metodu icin override kurallari gecerlidir. Yani SuperClassta public yapip SubClassta protected yapamayiz.
Bu kisimlarda sorun varsa override yazilarimi okumanizi oneririm.

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

*
*