Statyczność to następny temat stanowiący część podstawowej wiedzy w kierunku programowania. Nie będzie to budząca zaskoczenie wiadomość, że język C# również takie coś obsługuje. A jakże! W końcu to język obiektowy :D! A zatem, przywitajcie się z kolejnym słowem kluczowym, "static". "static" w języku C# nałożone na zmienną lub metodę zmienia kompletnie zasady gry :O!
Tweet |
"STATIC" W JĘZYKU C# RÓWNIEŻ DAJE TEN SAM EFEKT JAK W KAŻDYM INNYM JĘZYKU OBSŁUGUJĄCYM STATYCZNOŚĆ...
...i nie sposób znowu napomknąć o Javie, która jest w pewnym sensie "rodzicem" języka C#. Umiecie posługiwać się zmiennymi i metodami statycznymi w Javie? To z pełną satysfakcją oświadczam, że możecie na spokojnie cały artykuł "oblecieć wzrokiem" i popatrzeć jedynie na przykłady, ponieważ "static" w języku C# zachowuje się identycznie jak "static" w języku Java :D.
O CZYM W OGÓLE MOWA?
Cały czas mam na względzie czytelników, którzy nie mają pojęcia o co "come on". Statyczność polega na zdefiniowaniu takiej składowej, która w gruncie rzeczy będzie przynależeć nie do obiektu, tylko do samej klasy. Kiedy w trakcie nabywania doświadczenia przez Was będzie mowa o zmiennej statycznej, oznaczać to będzie umieszczenie nowej składowej w klasie (tak jak zwykle), ale dostęp do niej nie będzie mieć żaden obiekt! W takim razie kto będzie "posiadaczem"? Sama klasa :O! Już wyjaśniam.
PRZYKŁAD KODU ŹRÓDŁOWEGO
Rzućmy okiem na przykład. Posiadamy taką oto daną składową należącą do klasy "Point", która ma na celu zliczenie ile instancji tej klasy zostało utworzonych:
public class Point
{
public static int createdPoints = 0;
private int x, y;
public Point(int x, int y)
{
this.x = x;
this.y = y;
++createdPoints;
}
}
Do konstruktora klasy dodano także preinkrementację, żeby to zliczanie punktów faktycznie miało miejsce. Początkowo może się Wam wydawać to bezsensowne, gdyż możecie pomyśleć że wartość nie ulegnie zmianie, jednak ma to sens i zaraz się dowiecie z czego to wynika.
WYSTĘPOWANIE W KLASIE, A NIE W OBIEKCIE!
Co myślicie, że jak utworzycie obiekt punktu, to przedostaniecie się do tej danej tak jak zwykle?
Point point = new Point(3, 6);
Console.WriteLine(point.createdPoints); // błąd kompilacji
Nie! Ponieważ "static" w języku C# powoduje przeniesienie danej składowej do innej pamięci, w efekcie czego ona już nie jest dostępna po jednej sztuce dla każdej instancji, tylko jest to jedna wartość i to umieszczona w klasie! Tamto spowoduje błąd kompilacji, a poskutkuje tylko niniejszy kod:
Console.WriteLine(Point.createdPoints);
To już będzie OK. Statyczność to przede wszystkim zdefiniowanie dla klasy, a nie jej instancji. To jest pierwszy wniosek z dwóch.
TRWAŁOŚĆ WARTOŚCI
Przykład jaki podałem polega na konsekwentnym dodawaniu o jedno oczko do statycznego licznika w momencie utworzenia kolejnego punktu. "static" w języku C# nakłada jeszcze jedną cechę w związku "z przywiązaniem" do klasy. Wszystkie modyfikacje jakie dotkną zmienną statyczną są trwałe! To oznacza, że gdy podczas modyfikacji wartości instancji, ona u każdego jest inna, tak przy statycznym liczniku należącym do klasy jest identyczna, z racji jej unikatowości:
Point pointA = new Point(5, 2);
Console.WriteLine(Point.createdPoints);
Point pointB = new Point(1, 8);
Console.WriteLine(Point.createdPoints);
Oto macie drugi wniosek z dwóch (choć dotyczy on jedynie zmiennych): statyczność przechowuje wszystkie modyfikacje wartości z powodu występowania w klasie.
"static" w języku C# sprawia, że zmienna albo metoda staje się częścią KLASY. W związku z tym, odwołanie jest dostępne wyłącznie poprzez klasę, nie obiekt (o ile modyfikator dostępu na to zezwala).
A CO Z METODAMI?
Tytułem rozwiania wątpliwości: kiedy zdefiniujecie metodę statyczną, ona też będzie dotyczyć samej klasy. A to oznacza, że o ile modyfikator dostępu zezwala na uzyskanie do niej dostępu spoza klasy:
using System;
public class Point
{
// reszta zawartości
public static double Distance(Point pa, Point pb)
{
double x = pa.x - pb.x;
double y = pa.y - pb.y;
return Math.Sqrt(x*x + y*y);
}
}
tylko taki zapis będzie prawidłowym wywołaniem metody statycznej:
Console.WriteLine(Point.Distance(pointA, pointB));
Tak działa "static" w języku C# w całej okazałości! Nie ma tu żadnych wywołań z poziomu zmiennej obiektowej!
MIAŁO BYĆ JESZCZE O KLASIE
Wtrącę już tak na szybko na zakończenie. Klasa też może być statyczna i taką spokojnie można zdefiniować:
static class MyStaticClass
{
}
Różnica pomiędzy statyczną, a zwykłą? Instancja od klasy statycznej jest niemożliwa (słowo kluczowe "new"). Wszystko!
Skończyliśmy. Statyczność potrafi na początku sprawić trudności, jednak z czasem dociera do człowieka jak to trzeba rozumieć i co to takiego daje. Są o wiele trudniejsze zagadnienia jakimi trzeba się zająć :).