Statyczne i niestatyczne elementy klasy (static vs. non-static)

 

Elementy (atrybuty i metody) statyczne są powiązane z klasą, a elementy nie-statyczne są powiązane z konkretnymi obiektami - instancjami klasy.

Atrybut statyczny lub metoda statyczna jest nazywana odpowiednio atrybutem klasy oraz metodą klasy,

natomiast atrybut nie-statyczny lub metoda nie-statyczna jest nazywana odpowiednio atrybutaem obiektu oraz metodą obiektu danej klasy.

 

W programie obiektowym w Javie klasa jako "szablon" obiektów jest już sama w sobie istniejącym bytem - strukturą, z której możemy skorzystać, jeśli są w niej dostępne atrybuty klasy (atrybuty statyczne) i/lub metody klasy (metody statyczne).

Czyli jeśli mamy klasę i utworzymy obiekt tej klasy, to w rzeczywistości mamy już do dyspozycji w programie dwa elementy:

  • klasę jako strukturę szablonu z dostępnymi atrybutami statycznymi i metodami statycznymi,
  • obiekt tej klasy utworzony zgodnie z tym szablonem, w którym mamy dodatkowo dostęp do atrybutów niestatycznych i metod niestatycznych (atrybutów i metod obiektu), przy czym w obiekcie dostępne są także wszystkie elementy statyczne.

 

Do elementów statycznych mamy dostęp nawet bez tworzenia obiektu danej klasy. Dostęp do elementów statycznych uzyskujemy poprzez klasę - np. w pokazanym niżej przykładzie (zwróć uwagę na wielką literę oznaczającą nazwę klasy KlasaA):

KlasaA.trzeciaMetodaStatyczna();

Dlatego w metodach statycznych możemy korzystać wyłącznie z elementów statycznych (atrybutów i metod typu static).

Metody i atrybuty statyczne to tzw. metody i atrybuty klasy (a nie obiektu).

 

Do elementów nie-statycznych nie mamy dostępu, dopóki nie utworzymy obiektu danej klasy - czyli instancji klasy. Dopiero w konkretnym obiekcie danej klasy można uzyskać dostęp do elementów nie-statycznych (atrybutów i metod, dla których nie użyto słowa kluczoweto static). Zwróć uwagę, że wywołujemy metodę obiektu obiekt.

KlasaA obiekt = new KlasaA();
obiekt.drugaMetodaNIESTATYCZNA();

W metodach nie-statycznych możemy korzystać zarówno z elementów nie-statycznych jak i elementów statycznych.

Metody i atrybuty nie-statyczne to metody i atrybuty obiektu - konkretnego egzemplarza (instancji) klasy.

Modyfikując atrybut statyczny klasy, zmieniamy wartość tego atrybutu w "szablonie" i zmiana ta jest widoczna we wszystkich obiektach tej klasy.

 

Przykład użycia metod statycznych i nie-statycznych. Próba użycia metody nie-statycznej wewnątrz statycznej metody main powoduje błąd kompilacji.

public class KlasaA {

	public static void main( String[] argumenty ) {
		KlasaA.trzeciaMetodaStatyczna();	// wywołanie metody statycznej z klasy - UDANE
		//drugaMetodaNIESTATYCZNA(); // próba wywołania metody NIEstatycznej ze statycznej metody main() - zakończona błędem kompilacji
		//KlasaA.drugaMetodaNIESTATYCZNA(); // próba wywołania metody NIEstatycznej z klasy - zakończona błędem kompilacji

		KlasaA obiektKlasyA = new KlasaA();	// utworzenie obiektu

		obiektKlasyA.drugaMetodaNIESTATYCZNA();	// wywołanie metody NIEstatycznej z obiektu, a nie klasy - UDANE
		obiektKlasyA.trzeciaMetodaStatyczna(); // wywołanie metody statycznej z obiektu, a nie klasy - UDANE

	}

	void drugaMetodaNIESTATYCZNA() {	// metoda NIEstatyczna - metoda obiektu - instancji klasy
		System.out.println("WYWOŁANO DRUGĄ METODĘ - niestatyczną");
	}

	static void trzeciaMetodaStatyczna() {	// metoda statyczna - metoda klasy
		System.out.println("WYWOŁANO TRZECIĄ METODĘ - statyczną");		
	}	
}

Zauważ, że z obiektu możemy wywoływać metody zarówno statyczne jak i nie-statyczne. To samo dotyczy atrybutów - z obiektu mamy dostęp do atrybutów i metod zarówno nie-statycznych jak i statycznych.

Natomiast za pośrednictwem klasy możemy wywołać wyłącznie metody statyczne oraz uzyskać dostęp wyłącznie do atrybutów statycznych.

 

Dowód na to, że klasa jest "szablonem" i zmiana atrybutu statycznego jest widoczna we wszystkich obiektach utworzonych w oparci o ten "szablon". Zmieniając wartość atrybutu statycznego, zmieniamy ją dla wszystkich obiektów danej klasy. W pokazanym niżej przykładzie w obiekcie obiekt1 zmieniamy wartość statycznego atrybutu i natychmiast widać tę zmianę w obiekcie obiekt2:

UWAGA! Pokazany niżej kod kompiluje się przy użyciu kompilatora Java 8, natomiast w nowszej wersji Java 9 występuje błąd. Komunikat o błędzie nakazuje użycia nazwy klasy zamiast nazwy obiektu w odniesieniu do atrybutu statycznego - czyli np. nakazuje wpisać MojaKlasa.atrybutStatyczny zamiast obiekt1.atrybutStatyczny.

class MojaKlasa {
	static int atrybutStatyczny;
	int atrybutNiestatyczny;
}

public class Main {
	public static void main( String... args ) {
		MojaKlasa.atrybutStatyczny = 2;
		System.out.println( "MojaKlasa.atrybutStatyczny == " + MojaKlasa.atrybutStatyczny );

		MojaKlasa obiekt1 = new MojaKlasa();
		MojaKlasa obiekt2 = new MojaKlasa();

		System.out.println( "obiekt2.atrybutStatyczny == " + obiekt2.atrybutStatyczny );

		obiekt1.atrybutStatyczny = 11;

		System.out.println( "obiekt2.atrybutStatyczny == " + obiekt2.atrybutStatyczny );

	} 
}