środa, 23 lipca 2014

O stateczności słów kilka, czyli static (zmienne, metody, klasy)

Static - o co chodzi?

Programowanie obiektowe przyniosło pojęcie klas i obiektów. W odróżnieniu od programowania strukturalnego (np C) nie musimy już tworzyć często powielających się zmiennych, tylko wystarczy stworzyć instancję danej klasy (zwaną dalej obiektem).

Czasami jednak możemy odnieść wrażenie, że tworzymy nadmiarowo pewne obiekty tylko po to, żeby raz ich użyć.

Definicja

 Klasa statyczna jest swojego rodzaju odpowiednikiem obiektu - określamy pewną stałą strukturę metod lub zmiennych (stąd nazwa), które dostępne są globalnie, bez konieczności tworzenia obiektów danej klasy.

Zamiast tworzyć nowy obiekt, wystarczy wówczas odwołać się do klasy jak do obiektu,

np
public static class Test
    {

        public static int n = 50;
        public static void Sprawdz()
        {
            //rób coś
        }
    }


Później, w obrębie naszej przestrzeni nazw (namespace) metodę możemy wywołać w następujący sposób (bez konieczności deklarowania obiektu):

...
            Test.Sprawdz();
...


Widoczną zmienną również możemy modyfikować w dokładnie ten sam sposób:

...
            Test.n = 100;
...


Co więcej, jeśli zmienimy wartość zmiennej, zmiana będzie widoczna w obrębie działania naszego programu globalnie.

Przykład - klasa nie statyczna

Załóżmy, że tworzymy prostą aplikację obliczającą pole i obwód figur geometrycznych na potrzeby szkoły podstawowej. Nasz kod może wyglądać mniej więcej tak:

namespace matematykaDlaNajmlodszych
{
    class Program
    {
        public class Mojeliczenie
        {
           
        }

        public class Prostokat
        {

            public Prostokat(int A, int B)
            {
                a = A;
                b = B;
            }


            public int a;
            public int b;


            public int pole(int a, int b)
            {
                return a * b;
            }

            public int obwod(int a, int b)
            {
                return (2 * a) + (2 * b);
            }
        }


        static void Main(string[] args)
        {
            Console.WriteLine("a: {0}\nb: {1}", a, b);
           
           
            Prostokat p = new Prostokat();


            p.a = 2;
            p.b = 3;
 


            int pole = p.pole(p.a, p.b);
            Console.WriteLine("Pole prostokąta (a * b): {0}", pole);
            //Ok, ale co jeśli będę musiał częściej, w innych klasach obliczać pole prostokąta?
            //Przecież obliczenie pola prostokąta się nie zmieni!

            Console.WriteLine("Naciśnij dowolny przycisk aby kontynuować...");
            Console.ReadKey(false);     
        }
    }

}


Jak widzimy, wszystko jest ok, działa. Jest tylko jedna mała kwestia...
Jeśli w innej części  programu będziemy chcieli ponownie obliczyć pole prostokąta (np w obrębie innej klasy), znowu będziemy musieli zadeklarować obiekt klasy Prostokat...


Na szczęście ktoś wpadł na pomysł: Stwórzmy Static.

Zmieńmy zatem metody naszej klasy na statyczne...

        public class Prostokat
        {
            public static int pole(int a, int b)
            {
                return a * b;
            }

            public static int obwod(int a, int b)
            {
                return (2 * a) + (2 * b);
            }
        }


...i mała zmiana w metodzie Main...
        static void Main(string[] args)
        {
            int a = 2;
            int b = 3;
            Console.WriteLine("a: {0}\nb: {1}", a, b);
            //Tym razem metoda jest startyczna,
            //nie ma potrzeby deklarowania obiektu klasy Prostokat do obliczenia pola!
            int pole = Prostokat.pole(a, b);

            Console.WriteLine("Pole prostokąta (a * b): {0}", pole);
            Console.WriteLine("Naciśnij dowolny przycisk aby kontynuować...");
            Console.ReadKey(false);                 
        }


... i świat stał się piękniejszy!

Jak widać w przykładzie, metody statyczne wcale nie muszą znajdować się w klasie statycznej, w naszym przykładzie była to klasa publiczna.

Uwaga: 
Ponieważ nasza klasa Prostokat posiada już statyczną metodę pole(a,b), nie możemy wywołać tej metody z obiektu:

Prostokat p = new Prostokat(2,4);
int pole = p.pole(p.a, p.b);

Od tej pory do metody na obliczenie pola odwołujemy się tak:

            Prostokat p = new Prostokat(2,3);
            int pole = Prostokat.pole(p.a, p.b);


Uwaga #2:
Jeśli cała klasa będzie statyczna, wszystkie jej atrybuty (zmienne) i operatory (funkcje, metody) muszą być statyczne.
Nadal możemy określać poziom dostępu do elementów klasy za pomocą modyfikatorów public i private.

Uwaga #3, #4:
Metody statyczne nie mogą być wirtualne (w końcu jak statyczna to statyczna!)
Klasa statyczna nie może być klasą bazową (

Podsumowanie

Słowo Static wprowadza wiele dobrego, ponieważ dzięki temu nie zawsze musimy tworzyć instancję naszych klas, aby wykonać pewne działania.

Możemy tworzyć uniwersalne klasy, metody lub zmienne, które będą dostępne "od ręki" bez konieczności tworzenia "na chwilę" obiektów. 


Brak komentarzy:

Prześlij komentarz