statické klíčové slovo

Někdy chcete definovat člena třídy, který bude použit nezávisle na všech ostatních objektech této třídy. Přístup ke členu třídy je zpravidla organizován prostřednictvím objektu této třídy, ale zároveň je možné vytvořit člena třídy pro nezávislé použití bez odkazu na konkrétní instanci objektu. K vytvoření takového člena třídy stačí uvést hned na začátku jeho deklarace klíčové slovo statický.

Pokud je člen třídy deklarován jako statický, stane se dostupným před vytvořením jakýchkoli objektů jeho třídy a bez odkazu na jakýkoli objekt. Klíčové slovo static lze použít k deklaraci proměnných i metod. Nejběžnějším příkladem statického člena je metoda Main(), která je jako taková deklarována, protože musí být volána. operační systém na samém začátku běžícího programu.

Chcete-li použít člen typu static mimo třídu, stačí zadat název této třídy operátorem tečka. K tomu ale nemusíte vytvářet objekt. Ve skutečnosti není statický člen přístupný odkazem na objekt, ale podle názvu jeho třídy.

Proměnné deklarované jako statické jsou v podstatě globální. Když jsou objekty deklarovány ve své třídě, pak kopie typ proměnné statický není vytvořen. Místo toho všechny instance třídy sdílejí stejnou proměnnou typu static. Taková proměnná se před použitím ve třídě inicializuje.

Příklad použití statického klíčového slova:

Použití systému; pomocí System.Collections.Generic; pomocí System.Linq; pomocí System.Text; jmenný prostor ConsoleApplication1 ( class myCircle ( // 2 metody, které vracejí plochu a délku kruhu public static double SqrCircle(int poloměr) ( return Math.PI * poloměr * poloměr; ) public static double LongCircle(int poloměr) ( return 2 * Math.PI * radius; ) ) class Program ( static void Main(string args) ( int r = 10; // Volání metod z jiné třídy // bez vytvoření instance objektu této třídy Console.WriteLine("Area of ​​a kruh s poloměrem (0) = (1 :#.##)",r,myCircle.SqrCircle(r)); Console.WriteLine("Délka kruhu je (0:#.##)",myCircle. LongCircle(r)); Console.ReadLine(); ) ) )

Existuje řada omezení pro použití metod statického typu:

    Metoda typu static nesmí mít tento odkaz, protože taková metoda není spuštěna na žádném objektu

    V metodě typu static je povoleno přímo volat pouze jiné metody typu static, nikoli metodu instance ze stejné třídy. Jde o to, že metody instance fungují na konkrétních objektech a metoda statického typu se na objektu nevolá. Proto taková metoda nemá žádné objekty, se kterými by mohla pracovat.

    Podobná omezení platí pro data typu static. Pro metodu typu static jsou přímo přístupná pouze další data typu static definovaná v její třídě. Konkrétně nemůže pracovat s proměnnou instance své třídy, protože nemá objekty, se kterými by mohl pracovat.

Statické konstruktory

Konstruktor lze také deklarovat jako statický. Statický konstruktor se obvykle používá k inicializaci komponent, které se vztahují na celou třídu, nikoli na jedinou instanci objektu této třídy. Proto jsou členové třídy inicializováni pomocí statického konstruktoru před vytvořením jakýchkoli objektů této třídy:

Použití systému; pomocí System.Collections.Generic; pomocí System.Linq; pomocí System.Text; jmenný prostor ConsoleApplication1 ( class MyClass ( public static int a; public int b; // Statický konstruktor static MyClass() ( a = 10; ) // Běžný konstruktor public MyClass() ( b = 12; ) ) class Program ( static void Main (string args) ( Console.WriteLine("Přístup k instanci třídy a: " + MyClass.a); MyClass obj = new MyClass(); Console.WriteLine("Přístup k instanci třídy b: " + obj.b) ; Konzole .ReadLine(); ) ) )

Všimněte si, že konstruktor statického typu je volán automaticky při prvním načtení třídy a před konstruktorem instance. Z toho můžeme vyvodit obecnější závěr: statický konstruktor musí být proveden před jakýmkoli konstruktorem instance. Navíc statické konstruktory nemají modifikátory přístupu – mají výchozí přístup, a proto je nelze z programu volat.

Statické třídy

Třídu lze deklarovat jako statickou. Statická třída má dvě hlavní vlastnosti. Nejprve vytvořte statické objekty třídy je to zakázáno. A za druhé, statická třída by měla obsahovat pouze statické členy. Statická třída se vytvoří pomocí následujícího formuláře deklarace třídy, upraveného pomocí klíčového slova static.

název třídy statické třídy ( // ...

Statické třídy se používají hlavně ve dvou případech. Nejprve je při vytváření vyžadována statická třída metoda rozšíření. Metody rozšíření jsou většinou spojeny s jazykem LINQ. A za druhé, statická třída slouží k uložení kolekce navzájem souvisejících statických metod.

V tomto článku prozkoumáme statické metody v Javě a porovnáme Static a Instance. Hlavní věc, kterou je třeba si zapamatovat, je, že pokud použijete klíčové slovo static s jakoukoli metodou, nazývá se to statická metoda.

Co jsou statické metody v Javě?

Statické metody jsou metody v Javě, které lze volat bez vytvoření objektu třídy. Jsou dokumentovány názvem (třída kategorie).
Klíčové slovo statické lze použít s třídou, proměnnou, metodou a blokem. Statické členy patří do třídy a ne do konkrétní instance, což znamená, že pokud uděláte člen statický, můžete k němu přistupovat bez objektu. Vezměme si příklad, abychom to pochopili:

Zde máme statickou metodu myMethod(), kterou můžeme volat bez jakéhokoli objektu, protože když člena učiníme statickým, stane se na úrovni třídy. Pokud odstraníme statické klíčové slovo a změníme ho na nestatické, budeme muset vytvořit objekt třídy, který jej zavolá.

Statické členy jsou společné pro všechny instance (objekty) třídy, ale nestatické členy jsou samostatné pro každou instanci třídy.

Třída SimpleStaticExample ( // Toto je statická metoda static void myMethod() ( System.out.println("myMethod"); ) public static void main(String args) ( /* Můžeš vidíme, že voláme tuto * metodu, aniž bychom vytvořili jakýkoli objekt. */ mojeMetoda(); ))

Syntax

public static void geek(název řetězce) ( // kód, který se má provést....

Je uloženo v Permanent Generation, protože je spojeno s (třída kategorie), kde jsou, a ne s objekty této třídy. Nicméně jejich lokální proměnné, stejně jako argument(y), které jim byly předány, jsou v zásobníku.

Důležité body:

  • Statické metody spojené s třídou, ve které se nacházejí, tj. budou na ni odkazovat, i když nevytváří instanci třídy, tj. ClassName.methodName(args).
  • Jsou určeny pro sdílení všechny objekty vytvořené ze stejné třídy.
  • Statické metody nelze přepsat.

Příklad použití statických metod v Javě:

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

Závěr:
vaibhav
stín

Statické proměnné (statické) a jejich hodnoty (primitiva nebo reference) jsou definovány uvnitř třídy a uloženy v paměťovém prostoru PermGen.

Co když statická proměnná odkazuje na objekt?

statický int i = 1;
static Object obj = new Object();

První řádek je hodnota, která bude uložena v sekci PermGen. Na druhém řádku bude odkaz na objekt uložen v sekci PermGen a objekt, na který odkazuje, bude uložen v sekci haldy.

Kdy se používají?

  • Pokud máte kód, který lze sdílet všemi instancemi stejné třídy, vložte tento kus kódu do statické metody.
  • Nejprve nastavte statická přístupová pole pro třídu.

Co je metoda instance Java?

Metoda instance Java jsou způsoby, kterými lze vytvořit objekt třídy před jeho voláním. Abychom mohli zavolat metodu instance, musíme vytvořit objekt z kategorie, ve které je definován.

Public void flair(String name) // kód, který má být (spuštěn.... ) // návratový typ může být int, float String nebo uživatelsky definovaný datový typ.

Parametry (argumenty, které jim byly předány), stejně jako jejich lokální proměnné a návratová hodnota, jsou alokovány na zásobníku.

Důležité body:

  • Instance patří do objektu třídy, nikoli do třídy, tj. budou se na ně stále odkazovat tak, jak byly po vytvoření objektu třídy.
  • Každý samostatný objekt A vytvořený z (třída, kategorie) má svou vlastní kopii metody instance této třídy.
  • Lze je přepsat.

Instanční metoda nebo statická metoda v Javě?

  • Metoda instance bude mít přímý přístup k metodám instance a proměnným.
  • Metoda instance bude přistupovat přímo ke statickým proměnným a statickým metodám.
  • Statické metody budou přistupovat přímo ke statickým proměnným a metodám.
  • Statické metody nemají přímý přístup k metodám instance a proměnným instance. A statická metoda to nemůže použít, protože neexistuje žádná instance pro "toto", na kterou by se dalo odkazovat.

Pak k nim můžeme přistupovat přímo prostřednictvím názvu třídy a operátoru rozlišení rozsahu. Ale co když jsou statické členské proměnné soukromé? Zvažte následující kód:

V tomto případě nemůžeme přímo přistupovat k Anything::s_value z main(), protože tento člen je soukromý. K soukromým členům třídy se obvykle přistupuje prostřednictvím veřejných metod. I když bychom mohli vytvořit běžnou metodu pro přístup k s_value , museli bychom pak vytvořit objekt této třídy, abychom mohli metodu používat! Existuje lepší možnost: můžeme udělat metodu statickou.

Stejně jako statické členské proměnné, statické metody není vázán na žádný objekt jedné třídy. Zde je příklad výše, ale se statickou metodou:

class Cokoli ( private: static int s_value; public: static int getValue() ( return s_value; ) // statická metoda ); int Cokoli::s_value = 3; // definice statické členské proměnné int main() ( std::cout<< Anything::getValue() << "\n"; }

Protože statické metody nejsou vázány na konkrétní objekt, lze je volat přímo prostřednictvím názvu třídy a operátoru rozlišení rozsahu nebo prostřednictvím objektů třídy (to se však nedoporučuje).

Statické metody nemají *tento ukazatel

Statické metody mají dvě zajímavé vlastnosti. Za prvé, protože statické metody nejsou vázány na objekt, nemají ! To dává smysl, protože ukazatel *this vždy ukazuje na objekt, na kterém metoda pracuje. Statické metody nemusí fungovat přes objekt, takže ukazatel *this není potřeba.

Za druhé, statické metody mohou přímo přistupovat k ostatním statickým členům (proměnným nebo funkcím), ale nemají přístup k nestatickým členům. Je to proto, že nestatické členy patří k objektu třídy, ale statické metody ne!

Ještě jeden příklad

Statické metody lze definovat mimo tělo třídy. Funguje to stejně jako u běžných metod. Například:

#zahrnout class IDGenerator ( private: static int s_nextID; // deklarace statické členské proměnné public: static int getNextID(); // deklarace statické metody ); // Definice statické členské proměnné je mimo tělo třídy. Všimněte si, že zde nepoužíváme statické klíčové slovo // Spusťte generování ID na 1 int IDGenerator::s_nextID = 1; // Definice statické metody je mimo tělo třídy. Všimněte si, že zde nepoužíváme statické klíčové slovo 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; }

#zahrnout

classIDGenerator

soukromé:

static int s_dalsiID ; // deklarace statické členské proměnné

veřejnost:

static int getNextID(); // deklarace statické metody

// Začněte generovat ID od 1

int IDGenerator :: s_nextID = 1 ;

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

int main()

for (int počet = 0 ; počet< 4 ; ++ count )

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

návrat 0;

Výsledek spuštění výše uvedeného programu je:

Další ID je: 1
Další ID je: 2
Další ID je: 3
Další ID je: 4

Všimněte si, že protože všechny proměnné a funkce této třídy jsou statické, nepotřebujeme vytvářet objekt této třídy, abychom s ním mohli pracovat! Statická členská proměnná se používá k uložení hodnoty dalšího identifikátoru, který jí má být přiřazen, a statická metoda se používá k vrácení identifikátoru a jeho zvýšení.

Upozornění na třídy se všemi statickými členy

Buďte opatrní při psaní tříd se všemi statickými členy. I když takové „čistě statické třídy“ mohou být užitečné, mají také své nevýhody.

Za prvé, protože všechny statické členy jsou vytvořeny pouze jednou, nemůže existovat více kopií „čistě statické třídy“ (bez klonování třídy a jejího pozdějšího přejmenování). Pokud například potřebujeme dva nezávislé objekty třídy IDGenerator, pak to prostřednictvím „čistě statické“ třídy nebude možné.

C++ nepodporuje statické konstruktory

Pokud můžete inicializovat obyčejnou členskou proměnnou přes , pak byste logicky měli být schopni inicializovat statické členské proměnné pomocí statického konstruktoru. A zatímco některé moderní jazyky podporují statické konstruktory přesně pro tento účel, C++ mezi ně bohužel nepatří.

Pokud lze vaši statickou proměnnou inicializovat přímo, není potřeba žádný konstruktor: můžete definovat statickou členskou proměnnou, i když je soukromá. Ve výše uvedeném příkladu to provedeme pomocí s_nextID . Zde je další příklad:

třída Něco ( public: static std::vector s_mychars; ); std::vektor Něco::s_mychars = ( "o", "a", "u", "i", "e" ); // definuje statickou členskou proměnnou

třída Něco

veřejnost:

statický std :: vektor< char >s_mychars ;

std::vektor< char >Něco :: s_mychars = ( "o" , "a" , "u" , "i" , "e" ) ; // definuje statickou členskou proměnnou

Pokud inicializace vaší statické členské proměnné vyžaduje spuštění kódu (například smyčky), existuje několik různých způsobů, jak to provést. Následující způsob je nejlepší:

#zahrnout #zahrnout třída Něco ( private: static std::vector s_mychars; public: class _nested // definuje vnořenou třídu s názvem _nested ( public: _nested() // konstruktor _nested inicializuje naši statickou členskou proměnnou ( 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"); )); // Statická metoda pro výstup s_mychars static void getSomething() ( pro (auto const &element: s_mychars) std::cout<< element << " "; } private: static _nested s_initializer; // используем статический объект класса _nested для гарантии того, что конструктор _nested выполнится }; std::vectorNěco::s_mychars; // definujeme naši statickou členskou proměnnou Something::_nested Something::s_initializer; // definuje náš statický s_initializer, který zavolá _vnořený konstruktor pro inicializaci s_mychars int main() ( Something::getSomething(); return 0; )

#zahrnout

#zahrnout

třída Něco

soukromé:

statický std :: vektor< char >s_mychars ;

veřejnost:

třída_vnořená // definuje vnořenou třídu s názvem _nested

veřejnost:

nested() // Konstruktor _nested inicializuje naši statickou členskou proměnnou

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") ;

Většina klíčových slov C++ vám umožňuje udělat jednu věc. Int se používá k deklaraci celočíselné proměnné, nebo když funkce vrací celočíselnou hodnotu nebo bere celé číslo jako argument. Operátor new použijete k přidělení paměti a operátor delete k jejímu uvolnění. Můžete použít const k označení, že hodnotu proměnné nelze změnit. Ironií je, že statické klíčové slovo, přestože znamená „neměnný“, má několik (a zjevně nesouvisejících) použití. Klíčové slovo statické lze použít ve třech hlavních kontextech:

  • uvnitř funkce;
  • uvnitř definice třídy;
  • před globální proměnnou v souboru tvořícím vícesouborový program.

Nejjednodušší je použít statiku uvnitř funkce. Jednoduše to znamená, že po inicializaci proměnná zůstane v paměti až do konce programu. Můžete si to představit jako proměnnou, která si uchovává svou hodnotu, dokud program neskončí. Můžete například použít statickou proměnnou k zaznamenání počtu volání funkce jednoduchým přidáním řádků static int count = 0; a počítat++; do funkce. Protože počet je statická proměnná, řádek static int count = 0; bude proveden pouze jednou. Kdykoli je funkce volána, bude mít count poslední hodnotu, která jí byla přidělena.

Tímto způsobem můžete také použít statiku, abyste zabránili opětovné inicializaci proměnné uvnitř smyčky. Například v následujícím kódu bude proměnná number_of_times rovna 100, i když řádek static int number_of_times = 0; je uvnitř smyčky, kde se má spustit pokaždé, když program dosáhne smyčky. Trik je v tom, že klíčové slovo static zabraňuje opětovné inicializaci proměnné. Jednou z věcí při použití klíčového slova static je, že automaticky nastaví proměnnou na nulu – ale nespoléhejte na ni (nejasní vaše záměry).

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

Statické proměnné můžete použít k uložení informací o poslední hodnotě vrácené funkce, například pokud chcete uložit maximální hodnotu vypočítanou funkcí. Pokud analyzujete řetězec, můžete také uložit poslední znak vrácený funkcí, abyste jej mohli zavolat s argumentem označujícím, že by měla vrátit poslední znak.

Druhé použití static je v rámci definice třídy. Ačkoli většina proměnných deklarovaných v rámci třídy může mít v každé instanci třídy jinou hodnotu, statická pole třídy budou mít stejnou hodnotu pro všechny instance této třídy a není ani nutné vytvářet instanci této třídy. . Je užitečné myslet na statické proměnné třídy jako na uchovávající informace potřebné k vytvoření nových objektů (například v továrně tříd). Pokud například chcete očíslovat instance třídy, můžete použít statickou proměnnou ke sledování posledního použitého čísla. Je důležité poznamenat, že při použití statických proměnných třídy je dobré používat název_třídy::x; , nikoli instance_třídy.x; . To pomáhá programátorovi připomenout, že statické proměnné nepatří do stejné instance třídy a že nemusíte vytvářet instanci této třídy. Jak jste si již pravděpodobně všimli, můžete použít operátor rozsahu, :: , pro přístup k statice, když k ní přistupujete prostřednictvím názvu třídy.

Při ladění nebo implementaci programu pomocí static je důležité mít na paměti, že jej nemůžete inicializovat uvnitř třídy. Ve skutečnosti, pokud se rozhodnete zapsat celý kód třídy do hlavičkového souboru, nebudete moci ani inicializovat statickou proměnnou uvnitř hlavičkového souboru; udělejte to v souboru .cpp. Také musíte inicializovat statické členy třídy, jinak nebudou v rozsahu. (Syntaxe je trochu zvláštní: zadejte název_třídy::statická_proměnná = hodnota .)

Můžete mít také funkce statické třídy. Statické funkce jsou funkce, které nevyžadují instanci třídy a jsou volány stejným způsobem, analogicky se statickými proměnnými, se jménem třídy, a ne se jménem objektu. Například a_class::static_function(); , ne an_instance.function(); . Statické funkce mohou pracovat pouze se statickými členy třídy, protože neodkazují na konkrétní instance třídy. Statické funkce lze použít ke změně statických proměnných, ke sledování jejich hodnot - například můžete použít statickou funkci, pokud se rozhodnete použít počítadlo, abyste každé instanci třídy dali jedinečný identifikátor.

Můžete například použít následující kód:

Class user ( private: int id; static int next_id; public: static int next_user_id() ( next_id++; return next_id; ) // další metody pro uživatelskou třídu user() // konstruktor třídy ( id = user::next_id++; / / nebo volání metody, id = user.next_user_id(); ) ); int user::next_id = 0;

Pamatujte, že při nastavování musíte uvést typ statické proměnné!

uživatel a_user;

nastaví ID na další ID číslo, které nepoužívá žádný jiný uživatelský objekt. Všimněte si, že je dobrým stylem deklarovat identifikátor jako konstantu.

Poslední použití static je globální proměnná v souboru kódu. V tomto případě použití static znamená, že zdrojový kód v jiných souborech, které jsou součástí projektu, nemá přístup k proměnné. Proměnnou může vidět pouze kód ve stejném souboru (její rozsah je omezen na soubor). Tuto techniku ​​lze použít k modelování objektově orientovaného kódu, protože omezuje viditelnost proměnných a pomáhá tak předejít kolizím názvů. Tento způsob použití statiky je pozůstatkem z C.