statyczne słowo kluczowe

Czasami chcesz zdefiniować członka klasy, który będzie używany niezależnie od wszystkich innych obiektów tej klasy. Z reguły dostęp do składowej klasy organizowany jest poprzez obiekt tej klasy, ale jednocześnie możliwe jest stworzenie składowej klasy do samodzielnego użytku bez odwoływania się do konkretnej instancji obiektu. Aby stworzyć takiego członka klasy, wystarczy wskazać na samym początku jego deklaracji słowo kluczowe statyczny.

Jeśli element klasy jest zadeklarowany jako statyczny, staje się dostępny przed utworzeniem jakichkolwiek obiektów jego klasy i bez odniesienia do żadnego obiektu. Słowo kluczowe static może służyć do deklarowania zarówno zmiennych, jak i metod. Najczęstszym przykładem statycznego elementu członkowskiego jest metoda Main(), która jest zadeklarowana jako taka, ponieważ musi zostać wywołana. system operacyjny na samym początku uruchomionego programu.

Aby użyć składowej typu static poza klasą, wystarczy podać nazwę tej klasy za pomocą operatora kropki. Ale nie musisz do tego tworzyć obiektu. W rzeczywistości statyczny element członkowski nie jest dostępny przez odwołanie do obiektu, ale przez nazwę jego klasy.

Zmienne zadeklarowane jako statyczne są zasadniczo globalne. Kiedy obiekty są deklarowane w swojej klasie, wtedy kopia typ zmiennej statyczny nie jest tworzony. Zamiast tego wszystkie wystąpienia klasy mają tę samą zmienną typu static. Taka zmienna jest inicjowana przed użyciem w klasie.

Przykład użycia słowa kluczowego static:

Korzystanie z systemu; za pomocą System.Collections.Generic; za pomocą System.Linq; za pomocą System.Text; namespace ConsoleApplication1 ( class myCircle ( // 2 metody, które zwracają powierzchnię i długość okręgu public static double SqrCircle(int radius) ( return Math.PI * radius * radius; ) public static double LongCircle(int promieni) ( return 2 * Math.PI * radius; ) ) class Program ( static void Main(string args) ( int r = 10; // Wywołaj metody z innej klasy // bez tworzenia instancji obiektu tej klasy Console.WriteLine("Obszar okrąg o promieniu (0) = (1 :#.##)",r,myCircle.SqrCircle(r)); Console.WriteLine("Długość okręgu to (0:#.##)",myCircle. LongCircle(r)); Console.ReadLine(; ) ) )

Istnieje szereg ograniczeń dotyczących stosowania metod typu statycznego:

    Metoda typu static nie może mieć referencji this, ponieważ taka metoda nie jest wykonywana na żadnym obiekcie

    W metodzie typu static tylko inne metody typu static mogą być wywoływane bezpośrednio, a nie metoda instancji z tej samej klasy. Chodzi o to, że metody instancji działają na określonych obiektach, a metoda typu statycznego nie jest wywoływana na obiekcie. Dlatego taka metoda nie ma obiektów, na których mogłaby operować.

    Podobne ograniczenia dotyczą danych typu statycznego. W przypadku metody typu static tylko inne dane typu static zdefiniowane w jej klasie są bezpośrednio dostępne. W szczególności nie może operować na zmiennej instancji swojej klasy, ponieważ nie ma obiektów, z którymi mógłby operować.

Konstruktory statyczne

Konstruktor można również zadeklarować jako statyczny. Konstruktor statyczny jest zwykle używany do inicjowania składników, które mają zastosowanie do całej klasy, a nie do pojedynczego wystąpienia obiektu tej klasy. Dlatego elementy klasy są inicjowane za pomocą statycznego konstruktora przed utworzeniem jakichkolwiek obiektów tej klasy:

Korzystanie z systemu; za pomocą System.Collections.Generic; za pomocą System.Linq; za pomocą System.Text; przestrzeń nazw ConsoleApplication1 ( class MojaKlasa ( public static int a; public int b; // Konstruktor statyczny MyClass() ( a = 10; ) // Konstruktor zwykły public MojaKlasa() ( b = 12; ) ) class Program ( static void Main (string args) ( Console.WriteLine("Dostęp do instancji klasy a: " + MyClass.a); MyClass obj = new MyClass(); Console.WriteLine("Dostęp do instancji klasy b: " + obj.b) ; Konsola .ReadLine(; ) ) )

Należy zauważyć, że konstruktor typu statycznego jest wywoływany automatycznie, gdy klasa jest ładowana po raz pierwszy, a przed konstruktorem wystąpienia. Z tego możemy wyciągnąć bardziej ogólny wniosek: konstruktor statyczny musi zostać wykonany przed jakimkolwiek konstruktorem instancji. Co więcej, konstruktory statyczne nie mają modyfikatorów dostępu - mają domyślny dostęp i dlatego nie mogą być wywoływane z programu.

Klasy statyczne

Klasę można zadeklarować jako statyczną. Klasa statyczna ma dwie główne właściwości. Najpierw utwórz obiekty klasy statycznej to jest zabronione. Po drugie, klasa statyczna powinna zawierać tylko statyczne elementy. Klasa statyczna jest tworzona za pomocą następującego formularza deklaracji klasy, zmodyfikowanej za pomocą słowa kluczowego static.

nazwa klasy statycznej klasy ( // ...

Klasy statyczne są używane głównie w dwóch przypadkach. Po pierwsze, podczas tworzenia wymagana jest klasa statyczna metoda przedłużania. Metody rozszerzające są głównie związane z językiem LINQ. Po drugie, klasa statyczna służy do przechowywania kolekcji powiązanych ze sobą metod statycznych.

W tym artykule przyjrzymy się metodom statycznym w Javie i porównamy Static i Instance. Najważniejszą rzeczą do zapamiętania jest to, że jeśli użyjesz słowa kluczowego static z dowolną metodą, nazywa się to metodą statyczną.

Czym są metody statyczne w Javie?

Metody statyczne to metody w Javie, które można wywołać bez tworzenia obiektu klasy. Są one udokumentowane nazwą (klasa kategoria).
Słowo kluczowe static może być używane z klasą, zmienną, metodą i blokiem. Członkowie statyczni należą do klasy, a nie do konkretnej instancji, co oznacza, że ​​jeśli ustawisz element członkowski jako statyczny, możesz uzyskać do niego dostęp bez obiektu. Weźmy przykład, aby to zrozumieć:

Tutaj mamy statyczną metodę myMethod(), możemy wywołać tę metodę bez żadnego obiektu, ponieważ gdy uczynimy element statycznym, stanie się on poziomem klasy. Jeśli usuniemy słowo kluczowe static i uczynimy je niestatycznym, będziemy musieli utworzyć obiekt klasy, aby je wywołać.

Statyczne elementy członkowskie są wspólne dla wszystkich wystąpień (obiektów) klasy, ale niestatyczne elementy członkowskie są oddzielne dla każdej instancji klasy.

Class SimpleStaticExample ( // To jest metoda statyczna static void myMethod() ( System.out.println("myMethod"); ) public static void main(String args) ( /* Możesz zobacz, że wywołujemy tę metodę * bez tworzenia żadnego obiektu. */ mojaMetoda(); ) )

Składnia

public static void geek(String name) ( // kod do wykonania....

Jest przechowywany w Permanent Generation, ponieważ jest powiązany (klasa kategoria), gdzie się znajdują, a nie z obiektami tej klasy. Jednak ich zmienne lokalne, jak również przekazane im argumenty, znajdują się na stosie.

Ważne punkty:

  • Metody statyczne powiązane z klasą, w której się znajdują, tj. będą się do niej odwoływać, nawet jeśli nie tworzy instancji klasy, tj. NazwaKlasy.NazwaMetody(argumenty).
  • Przeznaczone są do dzielenie się wszystkie obiekty utworzone z tej samej klasy.
  • Nie można nadpisać metod statycznych.

Przykład wykorzystania metod statycznych w Javie:

Importuj java.io.*; class Flair( public static String FlairName = ""; public static void geek(String name) ( FlairName = nazwa; ) ) class GFG ( public static void main (args String) ( Flair.flair("vaibhav"); System.out .println(Flair.flairName); Flair obj = new Flair(); obj.flair("cień"); System.out.println(obj.flairName; ) )

Wniosek:
vaibhav
cień

Zmienne statyczne (statyczne) oraz ich wartości (prymitywy lub referencje) są definiowane wewnątrz klasy i przechowywane w przestrzeni pamięci PermGen.

Co się stanie, jeśli zmienna statyczna odwołuje się do obiektu?

statyczna int i = 1;
statyczny obiekt obj = nowy obiekt();

Pierwsza linia to wartość, która będzie przechowywana w sekcji PermGen. W drugim wierszu odwołanie do obiektu będzie przechowywane w sekcji PermGen, a obiekt, do którego się odwołuje, będzie przechowywany w sekcji sterty.

Kiedy są używane?

  • Jeśli masz kod, który może być współużytkowany przez wszystkie wystąpienia tej samej klasy, umieść ten fragment kodu w metodzie statycznej.
  • Przede wszystkim skonfiguruj statyczne pola dostępu dla klasy.

Co to jest metoda instancji Java?

Metoda instancji Java to sposoby, w jakie można utworzyć obiekt klasy przed jego wywołaniem. Aby wywołać metodę instancji, musimy stworzyć obiekt z kategorii, w której jest zdefiniowany.

Public void flair(String name) // kod do (wykonania.... ) // zwracany typ może być int, float String lub typem danych zdefiniowanym przez użytkownika.

Na stosie są alokowane parametry (przekazywane im argumenty), a także ich zmienne lokalne i zwracana wartość.

Ważne punkty:

  • Instancje należą do obiektu klasy, a nie do klasy, tj. nadal będą się do nich odwoływać po utworzeniu obiektu klasy.
  • Każdy oddzielny obiekt Utworzona z (klasa, kategoria) ma własną kopię metody(-ów) instancji tej klasy.
  • Można je obejść.

Metoda instancji czy metoda statyczna w Javie?

  • Metoda instancji będzie miała bezpośredni dostęp do metod instancji i zmiennych.
  • Metoda instancji będzie miała bezpośredni dostęp do zmiennych statycznych i metod statycznych.
  • Metody statyczne będą miały bezpośredni dostęp do zmiennych i metod statycznych.
  • Metody statyczne nie mogą uzyskać bezpośredniego dostępu do metod instancji i zmiennych instancji. A metoda statyczna nie może tego użyć, ponieważ nie ma instancji, do której można by się odwoływać „this”.

Następnie możemy uzyskać do nich bezpośredni dostęp poprzez nazwę klasy i operator rozpoznawania zakresu. Ale co, jeśli statyczne zmienne składowe są prywatne? Rozważ następujący kod:

W tym przypadku nie możemy bezpośrednio uzyskać dostępu do Anything::s_value z main(), ponieważ ten element członkowski jest prywatny. Zwykle dostęp do prywatnych członków klasy uzyskuje się za pomocą metod publicznych. Chociaż moglibyśmy stworzyć zwykłą metodę dostępu do s_value , musielibyśmy stworzyć obiekt tej klasy, aby użyć tej metody! Jest lepsza opcja: możemy uczynić metodę statyczną.

Podobnie jak statyczne zmienne składowe, metody statyczne nie jest powiązany z żadnym obiektem jednej klasy. Oto powyższy przykład, ale z metodą statyczną:

class Wszystko ( private: static int s_value; public: static int getValue() ( return s_value; ) // metoda statyczna ); int Wszystko::s_value = 3; // definicja statycznej zmiennej składowej int main() ( std::cout<< Anything::getValue() << "\n"; }

Ponieważ metody statyczne nie są powiązane z konkretnym obiektem, można je wywoływać bezpośrednio za pomocą operatora rozpoznawania nazw klas i zakresu lub obiektów klas (ale nie jest to zalecane).

Metody statyczne nie mają *tego wskaźnika

Metody statyczne mają dwie interesujące cechy. Po pierwsze, ponieważ metody statyczne nie są powiązane z obiektem, nie mają ! Ma to sens, ponieważ *this wskaźnik zawsze wskazuje na obiekt, nad którym pracuje metoda. Metody statyczne mogą nie działać przez obiekt, więc *ten wskaźnik nie jest potrzebny.

Po drugie, metody statyczne mogą bezpośrednio uzyskiwać dostęp do innych statycznych elementów członkowskich (zmiennych lub funkcji), ale nie mogą uzyskać dostępu do niestatycznych elementów członkowskich. Dzieje się tak, ponieważ niestatyczne składowe należą do obiektu klasy, ale metody statyczne nie!

Jeszcze jeden przykład

Metody statyczne można definiować poza treścią klasy. Działa to tak samo, jak w przypadku zwykłych metod. Na przykład:

#włączać class IDGenerator ( private: static int s_nextID; // deklaracja statycznej zmiennej składowej public: static int getNextID(); // deklaracja metody statycznej ); // Definicja statycznej zmiennej składowej znajduje się poza treścią klasy. Zauważ, że nie używamy tutaj słowa kluczowego static // Rozpocznij generowanie identyfikatora od 1 int IDGenerator::s_nextID = 1; // Definicja metody statycznej znajduje się poza treścią klasy. Zauważ, że nie używamy statycznego słowa kluczowego int IDGenerator::getNextID() ( return s_nextID++; ). int main() ( for (int count=0; count< 4; ++count) std::cout << "The next ID is: " << IDGenerator::getNextID() << "\n"; return 0; }

#włączać

classIDGenerator

prywatny :

statyczny int s_nextID ; // deklaracja statycznej zmiennej składowej

publiczny :

statyczny int getNextID(); // deklaracja metody statycznej

// Rozpocznij generowanie identyfikatora od 1

int IDGenerator :: s_nextID = 1 ;

int IDGenerator :: getNextID () ( return s_nextID ++ ; )

int main()

for (liczba int = 0 ; liczba< 4 ; ++ count )

std::cout<< "The next ID is: " << IDGenerator :: getNextID () << "\n" ;

zwróć 0 ;

Efektem uruchomienia powyższego programu jest:

Następny identyfikator to: 1
Następny identyfikator to: 2
Następny identyfikator to: 3
Następny identyfikator to: 4

Zauważ, że ponieważ wszystkie zmienne i funkcje tej klasy są statyczne, nie musimy tworzyć obiektu tej klasy, aby z nim pracować! Statyczna zmienna członkowska służy do przechowywania wartości następnego identyfikatora, który ma zostać do niej przypisany, a metoda statyczna służy do zwracania identyfikatora i zwiększania go.

Ostrzeżenie o klasach ze wszystkimi członkami statycznymi

Zachowaj ostrożność podczas pisania klas ze wszystkimi elementami statycznymi. Chociaż takie „czysto statyczne klasy” mogą być przydatne, mają też swoje wady.

Po pierwsze, ponieważ wszystkie statyczne składowe są tworzone tylko raz, nie może istnieć wiele kopii „czysto statycznej klasy” (bez klonowania klasy i późniejszej zmiany jej nazwy). Na przykład, jeśli potrzebujemy dwóch niezależnych obiektów klasy IDGenerator, to nie będzie to możliwe poprzez klasę „czysto statyczną”.

C++ nie obsługuje konstruktorów statycznych

Jeśli możesz zainicjować zwykłą zmienną składową za pośrednictwem , to logicznie rzecz biorąc, powinieneś być w stanie zainicjować statyczne zmienne członkowskie za pomocą statycznego konstruktora. I chociaż niektóre nowoczesne języki obsługują konstruktory statyczne właśnie w tym celu, C++ niestety nie jest jednym z nich.

Jeśli twoja zmienna statyczna może być zainicjowana bezpośrednio, nie jest potrzebny żaden konstruktor: możesz zdefiniować statyczną zmienną składową, nawet jeśli jest prywatna. Robimy to w powyższym przykładzie z s_nextID . Oto kolejny przykład:

class Something ( public: static std::vector s_mychary; ); std::wektor Coś::s_mychars = ( "o", "a", "u", "i", "e" ); // zdefiniuj statyczną zmienną składową

klasaCoś

publiczny :

std statyczny :: wektor< char >s_mychary ;

std::wektor< char >Coś :: s_mychars = ( "o" , "a" , "u" , "i" , "e" ) ); // zdefiniuj statyczną zmienną składową

Jeśli inicjowanie statycznej zmiennej składowej wymaga wykonania kodu (takiego jak pętla), można to zrobić na kilka różnych sposobów. Najlepszy jest następujący sposób:

#włączać #włączać class Coś ( private: static std::vector s_mychary; public: class _nested // zdefiniowanie klasy zagnieżdżonej o nazwie _nested ( public: _nested() // konstruktor _nested inicjalizuje naszą statyczną zmienną składową ( s_mychars.push_back("o"); s_mychars.push_back("a"); s_mychars.push_back () "u"); s_mychars.push_back("i"); s_mychars.push_back("e"); ) ); // Statyczna metoda wyprowadzania s_mychars static void getSomething() ( for (auto const &element: s_mychars) std::cout<< element << " "; } private: static _nested s_initializer; // используем статический объект класса _nested для гарантии того, что конструктор _nested выполнится }; std::vectorCoś::s_mychars; // zdefiniuj naszą statyczną zmienną składową Something::_nested Something::s_initializer; // zdefiniuj nasz statyczny s_initializer, który wywoła konstruktor _nested w celu zainicjowania s_mychars int main() ( Something::getSomething(); return 0; )

#włączać

#włączać

klasaCoś

prywatny :

std statyczny :: wektor< char >s_mychary ;

publiczny :

klasa_zagnieżdżona // zdefiniuj zagnieżdżoną klasę o nazwie _nested

publiczny :

zagnieżdżone() // _zagnieżdżony konstruktor inicjuje naszą statyczną zmienną składową

s_mychary . push_back("o") ;

s_mychary . push_back("a") ;

s_mychary . push_back("u") ;

s_mychary . push_back("i") ;

s_mychary . push_back("e") ;

Większość słów kluczowych C++ pozwala zrobić jedną rzecz. Używasz int do deklarowania zmiennej całkowitej lub gdy funkcja zwraca wartość całkowitą lub przyjmuje liczbę całkowitą jako argument. Używasz nowego operatora do przydzielania pamięci, a operatora usuwania do jej zwalniania. Możesz użyć const, aby wskazać, że nie można zmienić wartości zmiennej. Jak na ironię, słowo kluczowe static, chociaż oznacza „niezmienny”, ma kilka (i najwyraźniej niepowiązanych) zastosowań. Słowo kluczowe static może być używane w trzech głównych kontekstach:

  • wewnątrz funkcji;
  • wewnątrz definicji klasy;
  • przed zmienną globalną w pliku tworzącym program wieloplikowy.

Najłatwiejsze jest użycie statyki wewnątrz funkcji. Oznacza to po prostu, że po zainicjowaniu zmiennej pozostaje ona w pamięci do końca programu. Możesz myśleć o tym jako o zmiennej, która przechowuje swoją wartość do momentu zakończenia programu. Na przykład możesz użyć zmiennej statycznej do zarejestrowania, ile razy funkcja została wywołana, po prostu dodając wiersze static int count = 0; i liczyć++; w funkcję. Ponieważ count jest zmienną statyczną, wiersz static int count = 0; zostanie wykonany tylko raz. Za każdym razem, gdy funkcja jest wywoływana, count otrzyma ostatnią wartość.

W ten sposób można również użyć statycznego, aby zapobiec ponownej inicjalizacji zmiennej w pętli. Na przykład w poniższym kodzie zmienna number_of_times będzie równa 100, mimo że wiersz statyczny int number_of_times = 0; znajduje się wewnątrz pętli, gdzie ma być wykonywany za każdym razem, gdy program dotrze do pętli. Sztuczka polega na tym, że słowo kluczowe static zapobiega ponownej inicjalizacji zmiennej. Jedną z rzeczy związanych z używaniem słowa kluczowego static jest to, że automatycznie ustawia ono zmienną na zero — ale nie polegaj na nim (to sprawia, że ​​twoje intencje są niejasne).

For(int ix=0; ix< 10; ix++) { for(int iy = 0; iy < 10; iy++) { static int number_of_times = 0; number_of_times++; } }

Zmiennych statycznych można używać do przechowywania informacji o ostatniej wartości zwracanej funkcji, na przykład, jeśli chcesz przechowywać maksymalną wartość obliczoną z funkcji. Jeśli analizujesz ciąg, możesz również przechowywać ostatni znak zwracany przez funkcję, aby móc go wywołać z argumentem wskazującym, że powinien zwrócić ostatni znak.

Drugie użycie static znajduje się w definicji klasy. Podczas gdy większość zmiennych zadeklarowanych w ramach klasy może mieć inną wartość w każdym wystąpieniu klasy, statyczne pola klasy będą miały tę samą wartość dla wszystkich wystąpień tej klasy i nie jest nawet konieczne tworzenie instancji tej klasy . Przydatne jest myślenie o statycznych zmiennych klas jako przechowujących informacje potrzebne do tworzenia nowych obiektów (na przykład w fabryce klas). Na przykład, jeśli chcesz ponumerować wystąpienia klasy, możesz użyć zmiennej statycznej, aby śledzić ostatnią użytą liczbę. Należy zauważyć, że dobrą praktyką jest używanie statycznych zmiennych klas do używania nazwa_klasy::x; , a nie wystąpienie_klasy.x; . Pomaga to przypomnieć programiście, że zmienne statyczne nie należą do tej samej instancji klasy i że nie trzeba tworzyć instancji tej klasy. Jak już zapewne zauważyłeś, możesz użyć operatora zasięgu :: , aby uzyskać dostęp do statycznego dostępu poprzez nazwę klasy.

Ważne jest, aby pamiętać, że podczas debugowania lub implementowania programu za pomocą static , nie można go zainicjować wewnątrz klasy. W rzeczywistości, jeśli zdecydujesz się napisać cały kod klasy w pliku nagłówkowym, nie będziesz nawet w stanie zainicjować zmiennej statycznej wewnątrz pliku nagłówkowego; zrób to w pliku .cpp. Ponadto musisz zainicjować statyczne elementy członkowskie klasy, w przeciwnym razie nie będą one znajdować się w zakresie. (Składnia jest nieco dziwna: wpisz nazwa_klasy::zmienna_statyczna = wartość).

Możesz także mieć statyczne funkcje klas. Funkcje statyczne to funkcje, które nie wymagają instancji klasy i są wywoływane w ten sam sposób, przez analogię ze zmiennymi statycznymi, z nazwą klasy, a nie z nazwą obiektu. Na przykład a_class::static_function(); , a nie instancja.funkcja(); . Funkcje statyczne mogą działać tylko na statycznych elementach członkowskich klasy, ponieważ nie odnoszą się do konkretnych wystąpień klasy. Funkcje statyczne mogą służyć do zmiany zmiennych statycznych, śledzenia ich wartości - na przykład możesz użyć funkcji statycznej, jeśli zdecydujesz się na użycie licznika, aby nadać każdej instancji klasy unikalny identyfikator.

Na przykład możesz użyć następującego kodu:

Class user ( private: int id; static int next_id; public: static int next_user_id() ( next_id++; return next_id; ) // inne metody dla klasy użytkownika user() // konstruktor klasy ( id = user::next_id++; / / lub wywołanie metody, id = user.next_user_id(); ) ); int użytkownik::next_id = 0;

Pamiętaj, że podczas ustawiania musisz podać typ zmiennej statycznej!

użytkownik a_użytkownik;

ustawi ID na następny numer ID, który nie jest używany przez żaden inny obiekt użytkownika. Zauważ, że dobrym stylem jest deklarowanie identyfikatora jako stałej.

Ostatnim użyciem static jest zmienna globalna w pliku kodu. W takim przypadku użycie statycznego oznacza, że ​​kod źródłowy w innych plikach, które są częścią projektu, nie może uzyskać dostępu do zmiennej. Tylko kod w tym samym pliku może zobaczyć zmienną (jej zakres jest ograniczony do pliku). Ta technika może być używana do modelowania kodu zorientowanego obiektowo, ponieważ ogranicza widoczność zmiennych, a tym samym pomaga uniknąć kolizji nazw. Ten sposób używania statyki jest pozostałością po C.