Modifikátory Java. Modifikátory prístupu

Budeme hovoriť o modifikátoroch: čo sú modifikátory, rozsahy, modifikátory pre triedy, polia, metódy. Nemyslím si, že to bude nuda.

Modifikátory v jazyku Java sú kľúčové slová, ktoré dávajú triede, poľu triedy alebo metóde určité vlastnosti.

Na označenie viditeľnosti triedy jej metód a polí existujú 4 modifikátory prístupu:

  • súkromnéčlenovia triedy sú prístupní iba v rámci triedy;
  • balík-súkromné ​​alebo predvolené (predvolené)členovia triedy sú viditeľné vo vnútri balenia;
  • chránenéčlenovia triedy sú k dispozícii vo vnútri balíka a v odvodených triedach;
  • verejnostičlenovia triedy sú k dispozícii každému.

Ak si pamätáte, na konci, keď sme už importovali triedu Cat, sa nám stále vyskytla chyba pri kompilácii.

Ide o to, že sme nezaregistrovali žiadne modifikátory prístupu k našim poliam a metódam a majú predvolenú vlastnosť (členy triedy sú viditeľné vo vnútri balíka). Aby sme opravili chybu kompilácie nášho kódu a konečne ho spustili, musíme náš konštruktor a metódy zverejniť. Potom ich možno volať z iných balíkov.

Možno sa začnete pýtať: načo to všetko je? Prečo nezviditeľniť kód z akéhokoľvek balíka alebo triedy, ale potrebujete obmedziť prístup? Tieto otázky samy zmiznú, keď príde čas na písanie zložitých a ťažkopádnych projektov. Teraz, keď píšeme aplikácie, ktorých funkčnosť je obmedzená na jednu alebo dve triedy, potom sa zdá, že nemá zmysel čokoľvek obmedzovať.

Predstavte si, že máte triedu, ktorá zobrazuje objekt nejakého produktu. Napríklad auto. Auto môže mať cenu. Vytvorili ste cenové pole a mnoho ďalších polí, množstvo metód, ktoré sú zodpovedné za funkčnosť. Všetko sa zdá byť v poriadku. Auto vašej triedy je súčasťou obrovského projektu a všetci sú spokojní. Ale povedzme, že niekto náhodne alebo zámerne vytvoril inštanciu triedy auta a dal zápornú cenu. Môže mať produkt zápornú cenu? Toto je veľmi primitívny príklad a je nepravdepodobné, že sa to stane skutočný život ale myslím, že myšlienka je jasná. Niekedy je potrebné poskytnúť prístup nie priamo, ale prostredníctvom určitých metód. Môže sa stať, že kód je zodpovedný za funkčnosť iného kódu a nechcete, aby niekto menil a upravoval časť vášho kódu. Na tento účel existuje obmedzenie prístupu.

Modifikátor prístupu pre konštruktory, metódy a polia môže byť ľubovoľný. Trieda môže byť buď verejná alebo predvolená a v jednom súbore môže byť len jedna verejná trieda.

Zatiaľ dosť o modifikátoroch prístupu. V článku „Object-Oriented Programming“ si o nich povieme podrobnejšie, ale teraz si povieme niečo o ďalších modifikátoroch, ktorých je mimochodom veľa.

Teraz je na rade modifikátor statické. Môže sa použiť pred metódou, poľom alebo dokonca triedou, keď chceme deklarovať vnorenú triedu. V Jave môžete písať triedy do iných tried a ak je modifikátor pred triedou vo vnútri statickej triedy, potom sa takáto trieda nazýva vnorená, ak iný modifikátor alebo predvolená, potom sa takáto trieda nazýva interná. O vnorených a vnútorných triedach bude samostatný článok, pretože tam nie je všetko také jednoduché.

Statický modifikátor pred metódou alebo poľom označuje, že nepatria do inštancie tejto triedy. Čo to pre nás znamená? Keď sme pole triedy alebo metódu deklarovali ako statické, možno ich volať bez použitia inštancie triedy. Teda namiesto tejto konštrukcie: Cat cat = new Cat(); cat.method(), stačí napísať Cat.method(). Za predpokladu, že metóda je deklarovaná ako statická. Statické premenné sú rovnaké pre všetky objekty triedy. Majú jeden odkaz.

    modifikátory verejnej triedy (

    static int otherStaticField = 5 ;

    public static void myStaticMethod() (

    someField = "Moje pole" ;

    //nonStaticField = ""; chyba kompilácie

    //nemožno použiť nestatické polia

    //v statických metódach

    public void myNonStaticMethod() (

    otherStaticField = 4 ; //možno použiť statické polia

    //v nestatických metódach

    //hlavná metóda má tiež statický modifikátor

    new Modifiers() .myNonStaticMethod() ;

    Modificators.myStaticMethod(); //volanie statických metód a polí

    //cez classname.method

Ďalšou dôležitou poznámkou o statických modifikátoroch je, že statické polia sa inicializujú pri načítaní triedy. V rôznych druhoch testov Java môžete často nájsť kód takto:

Otázka: Čo bude výstup do konzoly? Je potrebné mať na pamäti, že statický blok sa v každom prípade zobrazí ako prvý. Ďalej nasleduje predvolený blok. Ďalej sa pozrite na obrazovku konzoly:

Ďalším modifikátorom, na ktorý sa pozrieme, je Konečný.

Myslím, že slovo finále hovorí samo za seba. Použitím posledného modifikátora hovoríte, že polia sa nedajú meniť, metódy sú prepísané a triedy sa nedajú dediť (o dedení bude samostatný článok). Tento modifikátor sa vzťahuje len na triedy, metódy a premenné (aj lokálne premenné).

S konečným modifikátorom metód a tried si povieme v článku OOP.

Ďalej budú modifikátory, ktoré začiatočníci alebo čitatelia tento cyklusčlánky od nuly nebudú veľmi jasné. A hoci vám ešte nemôžem všetko vysvetliť (kvôli tomu, že nepoznáte sprievodný materiál), stále vám odporúčam, aby ste sa s nimi oboznámili. Keď príde čas na použitie týchto modifikátorov, budete už rozumieť väčšine výrazov použitých nižšie.

Modifikátor synchronizované označuje, že metódu môže naraz použiť iba jedno vlákno. Aj keď vám to nemusí nič povedať, užitočnosť tohto modifikátora sa ukáže, keď budeme skúmať viacvláknové spracovanie.

Modifikátor prechodný- hovorí, že počas serializácie objektu by sa malo ignorovať určité pole. Takéto polia spravidla ukladajú medzihodnoty.

Modifikátor nestály- používa sa na multithreading. Keď bude pole s nestálym modifikátorom používané a upravované viacerými vláknami, tento modifikátor zaisťuje, že pole bude modifikované po jednom a nedôjde k zámene.

Modifikátor natívny pred deklaráciou metódy označuje, že metóda je napísaná v inom programovacom jazyku. Zvyčajne v jazyku C.

Modifikátor strictfp- Zabezpečuje vykonávanie operácií na číslach typu float a double (floating point) podľa normy IEEE 754. Alebo jednoduchšie povedané garantuje, že v rámci metódy budú výsledky výpočtov rovnaké na všetkých platformách.

O modifikátore som ešte nehovoril abstraktné. Stručne vám o tom poviem, pretože bez znalosti základov objektovo orientovaného programovania nevidím zmysel o tom hovoriť.

Triedu, ktorá má modifikátor abstract, nemožno vytvoriť inštanciu. Jediným účelom je rozšírenie. Abstraktná trieda môže obsahovať abstraktné aj bežné metódy.

O modifikátore abstrakt si povieme viac v článku OOP.

Týmto končí článok o modifikátoroch. Veľa sa o nich nepovedalo. Ale to je spôsobené tým, že ešte nemáme koncepty OOP. V niekoľkých článkoch doplníme poznatky o modifikátoroch a doplníme medzery.

Ktoré pridáte počas inicializácie na zmenu hodnôt. Jazyk Java má širokú škálu modifikátorov, z ktorých hlavné sú:

  • modifikátory prístupu;
  • Modifikátory triedy, metódy, premennej a vlákna sa nepoužívajú na prístup.

Ak chcete použiť modifikátor v jazyku Java, musíte zahrnúť jeho kľúčové slovo do definície triedy, metódy alebo premennej. Modifikátor musí prísť pred zvyšok operátora, ako je znázornené v nasledujúcich príkladoch:

public class className ( // ... ) private boolean myFlag; statické záverečné dvojité týždne = 9,5; chránený statický konečný int BOXWIDTH = 42; public static void main(Stringové argumenty) ( // telo metódy )

Modifikátory prístupu

Java poskytuje množstvo modifikátorov prístupu na nastavenie úrovní prístupu pre triedy, premenné, metódy a konštruktory. Existujú štyri prístupy:

  • Viditeľné v balíku (predvolené a nevyžaduje sa žiadny modifikátor).
  • Viditeľné iba pre triedu (súkromné).
  • Viditeľné pre všetkých (verejnosť).
  • Viditeľné pre balík a všetky podtriedy (chránené).

Predvolený modifikátor prístupu – žiadne kľúčové slovo

Predvolený modifikátor prístupu- znamená, že v jazyku Java explicitne nedeklarujeme modifikátor prístupu pre triedu, pole, metódu atď.

Premenná alebo metóda deklarovaná bez modifikátora riadenia prístupu je dostupná pre akúkoľvek inú triedu v rovnakom balíku. Polia v rozhraní sú implicitne verejné, statické, konečné a metódy v rozhraní sú štandardne verejné.

Príklad

Premenné a metódy môžu byť deklarované v jazyku Java bez akýchkoľvek modifikátorov, ako je znázornené v nasledujúcom príklade:

Verzia reťazca = "1.5.1"; boolean processOrder () ( return true; )

modifikátor súkromného prístupu

súkromný modifikátor- K metódam, premenným a konštruktérom, ktoré sú v jazyku Java deklarované ako súkromné, je možné pristupovať iba v rámci samotnej deklarovanej triedy.

Modifikátor súkromného prístupu je najobmedzujúcejšou úrovňou prístupu. Trieda a rozhrania nemôžu byť súkromné.

Premenné deklarované ako súkromné ​​môžu byť prístupné mimo triedy, ak sú v triede prítomné verejné metódy, ktoré ich prijímajú (pozri príklad a vysvetlenie nižšie).

Použitie súkromného modifikátora v jazyku Java je hlavným spôsobom skrytia údajov.

Príklad

Nasledujúca trieda používa súkromné ​​riadenie prístupu:

Verejná trieda Logger ( private String format; public String getFormat() ( return this.format; ) public void setFormat(String format) ( this.format = format; ) )

Tu je premenná formát trieda drevorubač je súkromný, takže iné triedy nemôžu získať a nastaviť jeho hodnotu priamo.

Aby sme túto premennú sprístupnili všetkým, definovali sme dve verejné metódy: getFormat(), ktorý vráti hodnotu formát, A setFormat(String), ktorý určuje jeho hodnotu.

modifikátor verejného prístupu

verejný modifikátor- trieda, metóda, konštruktor, rozhranie atď. deklarované ako verejné sú prístupné z ktorejkoľvek inej triedy. Preto k poliam, metódam, blokom deklarovaným vo verejnej triede možno pristupovať z ktorejkoľvek triedy patriacej do „vesmíru“ Java.

Ak sa však pokúšame o prístup k verejnej triede v inom balíku, verejná trieda musí byť importovaná.

Vďaka dedičnosti tried sú v Jave všetky verejné metódy a premenné triedy dedené jej podtriedami.

Príklad

Nasledujúca funkcia využíva riadenie verejného prístupu:

Verejné statické void main(Stringové argumenty) ( // ... )

Metóda Hlavná() musí byť verejný. V opačnom prípade ho nemožno zavolať z interpreta java na spustenie triedy.

modifikátor chráneného prístupu

chránený modifikátor- Premenné, metódy a konštruktory, ktoré sú deklarované ako chránené v nadtriede, môžu byť prístupné iba podtriedam v inom balíku alebo akejkoľvek triede v balíku chránenej triedy.

Modifikátor chráneného prístupu v jazyku Java nemožno použiť na triedy a rozhrania. Metódy a polia môžu byť vyhlásené za chránené, ale metódy a polia v rozhraní nemôžu byť vyhlásené za chránené.

Chránený prístup dáva podtriede možnosť použiť pomocnú metódu alebo premennú, čím bráni nesúvisiacej triede, aby sa ju pokúsila použiť.

Príklad

Nasledujúca rodičovská trieda používa chránené riadenie prístupu, takže jej podradená trieda prepíše metódu openSpeaker():

Class AudioPlayer ( chránený booleovský openSpeaker(Speaker sp) ( // podrobnosti implementácie ) ) class StreamingAudioPlayer ( boolean openSpeaker(Speaker sp) ( // podrobnosti implementácie ) )

Ak však definujeme metódu openSpeaker() ako chránený nebude prístupný zo žiadnej inej triedy ako AudioPlayer. Ak ho zadefinujeme ako verejný, stane sa dostupným pre každého. Ale naším zámerom je vystaviť túto metódu iba podtriede, a preto sme použili chránený modifikátor.

Pravidlá kontroly prístupu a dedenia

Nasledujúce pravidlá v jazyku Java sa vzťahujú na zdedené metódy:

  • Metódy deklarované ako verejné v nadtriede musia byť verejné aj vo všetkých podtriedach.
  • Metódy vyhlásené za chránené v nadtriede musia byť buď chránené alebo verejné v podtriedach; nemôžu byť súkromné.
  • Metódy deklarované ako súkromné ​​nededí každý, takže pre ne neexistuje žiadne pravidlo.

Na prístup sa nepoužívajú modifikátory triedy, metódy, premennej a vlákna

Java poskytuje množstvo modifikátorov nie pre prístup, ale pre implementáciu mnohých ďalších funkcií:

  • modifikátor statické používa sa na vytváranie metód a premenných tried;
  • modifikátor Konečný používa sa na dokončenie implementácie tried, metód a premenných;
  • modifikátor abstraktné potrebné na vytváranie abstraktných tried a metód;
  • modifikátory synchronizované A nestály sa používajú v Jave pre vlákna.

statický modifikátor

statický modifikátor- slúži na vytváranie metód a premenných tried.

statické premenné

Kľúčové slovo statické sa používa na vytvorenie premenných, ktoré budú existovať nezávisle od akýchkoľvek inštancií vytvorených pre triedu. V jazyku Java existuje iba jedna kópia statickej premennej, bez ohľadu na počet inštancií triedy.

Statické premenné sú známe aj ako premenné triedy. V jazyku Java nie je možné lokálne premenné deklarovať ako statické.

statické metódy

Kľúčové slovo statické sa používa na vytvorenie metód, ktoré budú existovať nezávisle od akýchkoľvek inštancií vytvorených pre triedu.

V Jave statické alebo statické metódy nepoužívajú žiadne premenné inštancie žiadneho objektu triedy, sú definované. Statické metódy preberajú všetky údaje z parametrov a niektoré z týchto parametrov sa vyhodnocujú bez odkazu na premenné.

K premenným a metódam triedy možno pristupovať pomocou názvu triedy, za ktorým nasleduje bodka a názov premennej alebo metódy.

Príklad

Statický modifikátor v jazyku Java sa používa na vytváranie metód triedy a premenných, ako je znázornené v nasledujúcom príklade:

Verejná trieda InstanceCounter ( private static int numInstances = 0; protected static int getCount() ( return numInstances; ) private static void addInstance() ( numInstances++; ) InstanceCounter() ( InstanceCounter.addInstance(); (main ) public static v argumentoid ) ( System.out.println("Začína od " + InstanceCounter.getCount() + "inštancia"); for (int i = 0; i

Získa sa nasledujúci výsledok:

Počnúc inštanciou 0 Vytvorených 500 inštancií

konečný modifikátor

konečný modifikátor- slúži na dokončenie implementácie tried, metód a premenných.

konečné premenné

Finálnu premennú je možné inicializovať iba raz. Referenčná premenná deklarovaná ako konečná nemôže byť nikdy priradená k odkazu na iný objekt.

Dáta vo vnútri objektu sa však dajú zmeniť. Stav objektu sa teda dá zmeniť, ale referencia nie.

Pri premenných v jazyku Java sa konečný modifikátor často používa so statickým, aby sa premenná triedy stala konštantou.

Príklad

public class Test( konečná hodnota int = 10; // Tu sú príklady deklarácií konštanty: public static final int BOXWIDTH = 6; static final String TITLE = "Manager"; public void changeValue(){ value = 12; //будет получена ошибка } } !}

konečné metódy

Finálna metóda nemôže byť prepísaná žiadnou podtriedou. Ako už bolo spomenuté, v jazyku Java konečný modifikátor zabraňuje modifikácii metódy podtriedou.

Hlavným zámerom urobiť metódu konečnou by bolo, aby sa obsah metódy nezmenil zo strany.

Príklad

Deklarácia metódy, ktorá používa konečný modifikátor v deklarácii triedy, je znázornená v nasledujúcom príklade:

Verejná trieda Test( public final void changeName()( // telo metódy ) )

záverečná trieda

Hlavným účelom použitia triedy deklarovanej ako konečná v jazyku Java je zabrániť triede v podtriede. Ak je trieda označená ako konečná, potom žiadna trieda nemôže zdediť žiadnu funkciu z konečnej triedy.

Príklad

verejný test záverečnej triedy ( // telo triedy )

abstraktný modifikátor

abstraktný modifikátor- používa sa na vytváranie abstraktných tried a metód.

abstraktná trieda

Abstraktná trieda nemôže byť vytvorená. Ak je trieda vyhlásená za abstraktnú, jej jediným účelom je rozšírenie.

Trieda nemôže byť abstraktná aj konečná, pretože konečnú triedu nemožno rozšíriť. Ak trieda obsahuje abstraktné metódy, potom musí byť vyhlásená za abstraktnú. V opačnom prípade sa vygeneruje chyba kompilácie.

Abstraktná trieda môže obsahovať abstraktné aj bežné metódy.

Príklad

abstract class Caravan( private double price; private String model; private String year; public abstract void goFast(); //abstract method public abstract void changeColor(); )

abstraktná metóda

Abstraktná metóda je metóda deklarovaná s akoukoľvek implementáciou. Telo metódy (implementácia) poskytuje podtrieda. Abstraktné metódy nemôžu byť nikdy konečné alebo prísne.

Každá trieda, ktorá rozširuje abstraktnú triedu, musí implementovať všetky abstraktné metódy nadtriedy, pokiaľ podtrieda nie je abstraktnou triedou.

Ak trieda v jazyku Java obsahuje jednu alebo viac abstraktných metód, potom musí byť trieda vyhlásená za abstraktnú. Abstraktná trieda nemusí obsahovať abstraktné metódy.

Abstraktná metóda končí bodkočiarkou. Príklad: public abstract sample();

Príklad

verejná abstraktná trieda SuperClass( abstract void m(); //abstraktná metóda ) class SubClass rozširuje SuperClass( // implementuje abstraktnú metódu void m()( ......... ) )

synchronizovaný modifikátor

synchronizovaný modifikátor

Kľúčové slovo synchronizované sa používa na označenie toho, že k metóde môže naraz pristupovať iba jedno vlákno. V jazyku Java je možné synchronizovaný modifikátor použiť s ktorýmkoľvek zo štyroch modifikátorov úrovne prístupu.

Príklad

verejné synchronizované void showDetails()( ....... )

prechodný modifikátor

Premenná inštancie označená ako prechodný indikuje virtuálny prístroj Java (JVM) na preskočenie určitej premennej pri serializácii objektu, ktorý ju obsahuje.

Tento modifikátor je zahrnutý v príkaze, ktorý vytvára premennú triedy predchodcu premennej alebo typu údajov.

Príklad

verejný prechodný int limit = 55; // nebude pretrvávať public int b; // sa uloží

prchavý modifikátor

prchavý modifikátor- sa používajú v Jave pre vlákna.

V Java sa volatile modifikátor používa na to, aby JVM vedel, že vlákno s variabilným prístupom by malo vždy zlúčiť svoju vlastnú kópiu premennej s hlavnou kópiou v pamäti.

Prístup k nestálej premennej synchronizuje všetky skopírované premenné uložené v pamäti cache Náhodný vstup do pamäťe. Volatile je možné použiť iba na premenné inštancie, ktoré sú typu objekt alebo súkromné. Odkaz na nestály objekt môže mať hodnotu null.

Príklad

public class MyRunnable implementuje Runnable( private volatile boolean active; public void run()( active = true; while (active)( // riadok 1 // tu je nejaký kód) ) public void stop()( active = false; / / riadok 2))

Run() sa zvyčajne volá v jednom vlákne (toto je prvýkrát, čo začnete používať Runnable v jazyku Java) a stop() sa volá v inom vlákne. Ak sa aktívna hodnota uložená vo vyrovnávacej pamäti používa na riadku 1, cyklus sa nemôže zastaviť, kým na riadku 2 nenastavíte hodnotu active na hodnotu false.

V ďalšej lekcii si rozoberieme základné operátory používané v jazyku Java. Táto časť vám poskytne prehľad o tom, ako ich môžete použiť pri vývoji aplikácie.

Je možné ovládať, ktoré časti programu môžu pristupovať k členom triedy. Kontrola prístupu pomáha predchádzať zneužitiu. Nie je vždy žiaduce mať prístup k jednej premennej alebo metóde triedy, ktorá by mala fungovať iba v rámci samotnej triedy.

Spôsob prístupu je definovaný modifikátor prístupu, ktorý sa dopĺňa pri vyhlásení. Celkovo sú štyri:

  • súkromné ​​(zatvorené)
  • verejný (otvorený)
  • chránený (chránený)
  • predvolený prístup, keď nie je prítomný žiadny modifikátor

Príklady deklarácií modifikátorov (musí byť vždy na prvom mieste):

public int i; súkromné ​​dvojité j, k; private int createMethod(int a) (...); verejná trieda Cat()

Ako vidíte, modifikátor je použiteľný pre premennú, metódu, triedu.

verejnosti

Pri použití kľúčového slova verejnosti hovoríte, že deklarácia člena triedy, ktorá nasleduje, je prístupná každému z akéhokoľvek iného kódu vo vašom projekte.

Predpokladajme, že trieda je deklarovaná ako verejnosti a má dva spôsoby. Jeden súkromné, druhý - verejnosti. Budete mať prístup do triedy a druhý metóda, ale nie do prvej, napriek tomu, že samotná trieda je verejná.

súkromné

Kľúčové slovo súkromné znamená, že prístup k členovi triedy nie je udelený nikomu okrem metód tejto triedy. Iné triedy v rovnakom balíku tiež nemajú prístup k súkromným členom.

Všetky pomocné metódy tried by mali byť deklarované ako súkromné aby sa zabránilo ich náhodnému volaniu v dávke. To isté platí pre súkromné ​​polia v rámci triedy.

chránené

Kľúčové slovo chránené sa spája s konceptom dedičnosti, pri ktorom sa do už existujúcej triedy (základnej triedy) pridávajú noví členovia, pričom pôvodná implementácia zostáva nezmenená. Môžete tiež zmeniť správanie existujúcich členov triedy. Ak chcete vytvoriť novú triedu založenú na existujúcej, použite kľúčové slovo predlžuje.

Keď sa vytvorí nový balík pomocou dedenia z triedy v inom balíku, nová trieda má prístup iba k verejným členom v pôvodnom balíku. Niekedy musí tvorca základnej triedy poskytnúť prístup k určitej metóde odvodeným triedam, ale skryť ju pred všetkými ostatnými. V týchto prípadoch sa používa kľúčové slovo chránené. špecifikátor chránené poskytuje aj prístup v rámci balíka, t.j. členovia s týmto špecifikátorom sú dostupné pre iné triedy v rovnakom balíku.

V predvolenom nastavení, ak sa nepoužije žiadny modifikátor, člen triedy sa považuje za verejného v rámci svojho vlastného balíka, ale nie je dostupný pre kódovanie mimo tohto balíka. Ak sú všetky triedy vášho projektu v rovnakom balíku, potom je v podstate premenná bez modifikátora verejná ( verejnosti).

Predstavte si fiktívnu triedu SillySensor

Verejná trieda SillySensor ( private int sensorData; public SillySensor() ( sensorData = 0; ) private void calibrate(int iSeed) ( // kód pre kalibráciu ) protected void seedCalibration(int iSeed) ( calibrate(iSeed); ) public int getSensorData( ) ( // Skontrolujte snímač tu vráťte údaje snímača; ) )

Trieda je deklarovaná ako verejnosti a dostupné v iných triedach. Trieda má premennú senzorové údaje, ktorá je dostupná len vo svojej triede (súkromná). Konštruktor je dostupný v iných triedach ( verejnosti). Metóda kalibrovať () funguje iba v rámci triedy ( súkromné). Metóda seedCalibration() dostupné vo svojej triede alebo v podtriede ( chránené). Metóda getSensorData() dostupné v iných triedach ( verejnosti).

5

Videl som nejaké diskusie na StackOverflow na túto tému, ale nevidím nič, čo by mi pomohlo pochopiť nasledujúci bod:

Pochádzam z prostredia C++ a nedávno som sa začal učiť Javu. V C++ keď chránené, používa sa iba podtrieda, ktorá má prístup k členovi (podobne ako pole v Jave).

V C++ sú tiež „priateľské“ triedy, ktoré majú prístup k súkromným/zabezpečeným triedam, ktoré poskytujú „priateľstvo“. Je to trochu ako modifikátor poľa "balík" v Jave (predvolený modifikátor poľa), okrem toho, že v C++ priateľstvo poskytuje prístup všetkým súkromným členom, ale v Jave je prístup z tried v rovnakom balíku špecifický pre pole triedy,

Čo nemôžem zistiť, za predpokladu, že chcem udeliť prístup iba k podtriedam, je to, čo môžem urobiť v C++ deklarovaním chránených členov v triede, ktorá „neposkytuje“ priateľskosť.

Ale v Jave neviem, ako to urobiť, pretože s modifikátorom poľa "protected" - dávam tiež prístup ku všetkým triedam v balíku. Jediný spôsob, ako to môžem urobiť, je deklarovať chránené pole a izolovať triedu vo vašom balíku.

Z toho usudzujem, že zoskupovanie tried do jedného balíka by sa malo robiť na základe „priateľstva“ medzi triedami. Je to skutočne hlavný faktor pri zoskupovaní balíkov?

Ešte jednej veci nerozumiem, v Jave, za predpokladu, že mám v triede A dve polia: b, c. Chcem dať B prístup k b, ale nie k, a chcem dať C prístup k c, ale nie k b. a do "Svetu" chcem b, c skryť. Ako to môžem spraviť? Predpokladám, že B, C musia byť v rovnakom balíku ako A. , ale deklarovaním b, c s balík modifikátor Povoľujem B, C prístup k b aj c. Existuje spôsob, ako to urobiť v Jave?

Dúfam v nejaké vysvetlenie tejto otázky

11

Lepšia otázka, ak je pre vás menej užitočná, by bola užšia a konkrétnejšia. Všeobecná otázka „všetko o súkromí v Jave a C++ a ako sa líšia“ je viac než príliš široká. Môžete sa opýtať viac konkrétna otázka o konkrétnejšom probléme? - Yakk 4. marca 15 2015-03-04 16:38:58

  • 4 odpovede
  • Triedenie:

    Aktivita

2

V C++, keď sa používa ochrana, môže k prvku pristupovať iba podtrieda (podobne ako pole v Jave).

Špecifikátory prístupu sú aj pre členské funkcie/metódy, nielen pre členské premenné.

V C++ existujú aj triedy „friend“, ktoré môžu mať prístup k súkromným/chráneným modulom triedy, čo dáva „priateľstvo“. Toto je trochu ako modifikátor poľa "balík" v Jave (predvolený modifikátor poľa), až na to, že v C++ priateľstvo poskytuje prístup všetkým súkromným členom, ale v Jave je prístup z tried v rovnakom balíku špecifický pre pole triedy.

Existujú nielen triedy priateľov, ale aj funkcie.

Je pravda, že prístup k súkromným častiam Java je podobný, ale nie je to úplná náhrada. Je lepšie povedať, že tieto dve funkcie majú podmnožina problémy, ktoré riešia. Existujú problémy, ktoré môže vyriešiť priateľ, ale nie súkromne s balíkom, a naopak.

Čo som nemohol zistiť, za predpokladu, že chcem udeliť prístup iba k podtriedam, je to, čo môžem urobiť v C++ vyhlásením používateľov za chránených v triede, ktorá „nedáva“ priateľstvo.

Ale v Jave neviem, ako to môžem urobiť,

Odpoveď: Nemôžeš.

keďže s modifikátorom poľa "protected" - tiež udeľujem prístup ku všetkým triedam v balíku.

Jediný spôsob, ako nájdem, je deklarovať chránené pole a mať triedu izolovanú v jeho balíku.

Technicky áno. To však vytvára ďalšie problémy. Vaša trieda už nebude mať prístup k súkromným častiam svojho predchádzajúceho balíka. Povedzme, že vaša BaseClass bola v com.example.one . Presuniete ho na com.example.two . Teraz už nebude môcť pristupovať k iným triedam privátnych balíkov com.example.one .

Je to skutočne hlavný faktor pri zoskupovaní balíkov?

Áno, Java je navrhnutá tak. Si môžete vyskúšať bojovať proti pravidlám jazyka, ale je to prehratý boj v akomkoľvek programovacom jazyku.

Ďalšia vec, ktorej nerozumiem, je v Jave, za predpokladu, že mám v triede A dve polia: b, c. Chcem dať B prístup k b, ale nie k, a chcem dať C prístup k c, ale nie k b. a vo "World" chcem, aby sa b, c skryli. Ako to môžem spraviť?

Nedá sa to urobiť čistým spôsobom (myslím tým čistým: bez akýchkoľvek hackov, ktoré by vyžadovali, aby ste skontrolovali zásobník volaní za behu a vyvolali výnimky).

Ak vás tento scenár znepokojuje, keďže vyvíjate verejné API, low-tech riešením, ktoré zvyčajne funguje skvele, je vytvorenie jedného alebo viacerých *.internal balíčkov a jasne zdokumentujte skutočnosť, že by sa nemali používať v klientsky kód.

1

To je poriadna kopa otázok...

Ale v Jave neviem, ako to môžem urobiť, pretože na základe použitia modifikátora poľa "chránené" tiež udeľujem prístup ku všetkým triedam v balíku.

V skutočnosti neexistuje spôsob, ako udeliť prístup iba podtriedam a nie triedam v rovnakom balíku. Bolo to dizajnové rozhodnutie urobené pred storočiami...

Jediný spôsob, ako to môžem urobiť, je vyhlásiť chránené pole a izolovať ho v mojom balíku.

To je technicky správne, aj keď to bude málo užitočné. Balenie tried slúži na zoskupovanie súvisiacich tried, kde „súvisiace“ znamená „triedy, ktoré spĺňajú konkrétny vzťah“, t. j. patria do rovnakého prípadu použitia, patria do rovnakej architektonickej úrovne, sú v rovnakých entitách atď.

Z toho usudzujem, že zoskupovanie tried do jedného balíka by sa malo robiť na základe „priateľstva“ medzi triedami. Je to skutočne hlavný faktor pri zoskupovaní balíkov?

Domnievam sa, že som na to už odpovedal v predchádzajúcom odseku: balenie je určené na zoskupovanie súvisiacich tried podľa určitých špecifických kritérií.

Pre vaše triedy A, B a C, napríklad s atribútmi:

Myslím, že B, C by mali byť oba v rovnakom balíku ako A. a deklarujúce b, s modifikátorom balenia nechám B, C prístup k b aj c. Existuje spôsob, ako to urobiť v jazyku Java?

Odpoveď je nie, neexistuje žiadny jednoduchý a čistý spôsob, ako to urobiť. Mohli by ste to dosiahnuť pomocou niektorých hackov alebo pokročilejších techník, ale opäť to bola súčasť rozhodnutí, ktoré urobili dizajnéri jazykov už dávno...

0

Krátka odpoveď: neexistuje spôsob, ako to urobiť.

Ak sa obávate narušenia v dôsledku vloženia klientov triedy do balíka s cieľom získať neoprávnený prístup, môžete presunúť citlivý kód do samostatného balíka a zapečatiť balík v nádobe, na ktorú ho doručíte: http://docs.oracle .com/javase/tutorial /deployment/jar/sealman.html

1

Implicitne sa predpokladá, že všetky triedy v balíku sa navzájom "poznajú" (pretože ich napísala tá istá osoba/spoločnosť/organizácia). Takže buď nezískajú prístup k chráneným poliam, alebo ak áno, vedia, ako to urobiť správne.

Predpokladá sa, že triedy v tom istom balíku sú vzájomne prepojené viac ako rodič s odvodenou triedou, pretože odvodenú triedu môže v skutočnosti napísať niekto iný. Preto sa rozhodli, že súkromná ochrana je viac obmedzená ako bezpečná.

Takže si myslím, že sa nemusíte starať o to, ako môžu triedy v tom istom balíku pristupovať k svojim poliam. Vo všeobecnosti túto funkciu nepoužívam okrem prípadov, keď píšem iterátory.

Ak máte dve polia, môžete z nich vytvoriť vnútorné triedy, aby mali prístup k súkromným poliam (opäť logika: ak je trieda v inej triede, vie o sémantike tejto triedy) a môže poskytnúť prístup k ich odvodeným poliam. triedy prostredníctvom chránených metód.

Samozrejme by ste mohli prísť s komplexným protokolom výmeny tokenov, aby bolo toto pole dostupné iba pre inštancie B/C, ale to by bola skvelá réžia a ďalší objekt by stále mohol používať reflexiu na prístup ku všetkým súkromným členom, ak ho nezakážete. s bezpečnostnými politikami, čo zvyčajne nie je tento prípad, ale opäť, o bezpečnostných politikách v konečnom dôsledku rozhoduje vlastník JVM.

Takže nakoniec preferovaný spôsob, ako urobiť to, čo hovoríte v Jave, je buď ich vložiť do rovnakého balíka, alebo napísať B a C ako vnútorné triedy A, aby mohli priamo pristupovať k súkromným členom A a vystaviť ich odvodeným triedam.

Verejná trieda A ( verejná statická abstraktná trieda B ( chránená Whatever getWhatever(A a) ( return a.b; ) chránená void setWhatever (A a, akákoľvek hodnota) ( ​​a.b = hodnota; ) ) verejná statická abstraktná trieda C ( chránená Whatever getWhatever (A a) ( return a.c; ) protected void setWhatever(A a, akákoľvek hodnota) ( ​​a.c = hodnota; ) ) private Whatever b; private Whatever c; )

ešte raz, vždy predpokladáte, že triedy v tom istom balíku nikdy nič nepokazia.

Ahoj! V dnešnej prednáške sa zoznámime s pojmom „ modifikátory prístupu a zvážte príklady práce s nimi. Hoci slovo „zoznámiť sa“ nebude celkom správne: väčšinu z nich už poznáte z predchádzajúcich prednášok. Pre každý prípad si osviežme pamäť toho hlavného. Modifikátory prístupu sú najčastejšie kľúčové slová, ktoré regulujú úroveň prístupu k rôznym častiam vášho kódu. Prečo "najčastejšie"? Pretože jeden z nich je štandardne nastavený a nie je označený kľúčové slovo:) V Jave sú štyri modifikátory prístupu. Uvádzame ich v poradí od najprísnejších po najviac „mäkké“:

  • súkromné;
  • chránené;
  • default (balík je viditeľný);
  • verejnosti.
Pozrime sa na každú z nich, rozhodnime sa, kedy nám môžu byť užitočné a uveďme príklady :)

súkromný modifikátor


Súkromné ​​je najviac reštriktívny modifikátor prístupu. Obmedzuje viditeľnosť údajov a metód na jednu triedu. Tento modifikátor poznáte z prednášky o getroch a setroch. Pamätáte si tento príklad? public class Cat ( public String name; public int age; public int weight; public Cat (meno reťazca, int vek, int váha) ( this . name = meno; this . age = vek; this . weight = váha; ) public Cat () ( ) public void sayMeow () ( System. out. println ("Meow!" ) ; ) ) public class Main ( public static void main (String args) ( Cat cat = new Cat () ; cat. name = " " ; kat. vek = - 1000 ; kat. hmotnosť = 0; ) ) Venovali sme sa tomu v jednom z článkov skôr. Tu sme urobili vážnu chybu: otvorili sme naše údaje, v dôsledku čoho sa kolegovia programátori dostali priamo k poliam triedy a zmenili ich hodnotu. Navyše, tieto hodnoty boli priradené bez kontrol, v dôsledku čoho je v našom programe možné vytvoriť mačku s vekom -1000 rokov, menom "" a váhou 0. Na vyriešenie tohto problému sme použité getre a setters a tiež obmedzený prístup k údajom pomocou modifikátora private. public class Cat ( private String name; private int age; private int weight; public Cat (meno reťazca, int vek, int váha) ( this . name = meno; this . age = vek; this . weight = váha; ) public Cat () ( ) public void sayMeow () ( System. out. println ("Meow!" ) ; ) public String getName () ( návratový názov; ) public void setName (String name) ( this . name = name; ) public int getAge () ( návratový vek; ) public void setAge (int vek) ( this . age = vek; ) public int getWeight () ( return weight; ) public void setWeight (int weight) ( this . weight = weight; ) ) V skutočnosti , obmedzenie prístupu k poliam a implementácia getter-setters je najbežnejším prípadom použitia pre súkromnú prácu v reálnej práci. Teda implementácia zapuzdrenia v programe je hlavným účelom tohto modifikátora. To sa mimochodom netýka len polí. Predstavte si, že vo vašom programe je metóda, ktorá implementuje nejakú VEĽMI zložitú funkcionalitu. Ako príklad vymyslieť niečo také... Povedzme, že vaša metóda readDataFromCollider() vezme adresu s údajmi ako vstup, načíta údaje z Large Hadron Collider v bajtovom formáte, prevedie tieto údaje na text, zapíše ich do súboru a vytlačí to von. Aj popis metódy vyzerá strašidelne, nieto ešte kód :) Pre zvýšenie čitateľnosti kódu by bolo dobré nepísať zložitú logiku metódy na jedno miesto, ale radšej rozčleniť funkcionalitu na samostatné metódy. Napríklad metóda readByteData() je zodpovedná za čítanie dát, convertBytesToSymbols() konvertuje dáta načítané z collider na text, saveToFile() uloží prijatý text do súboru a printColliderData() vytlačí náš dátový súbor. Metóda readDataFromCollider() by bola nakoniec oveľa jednoduchšia: verejná trieda ColliderUtil ( public void readDataFromCollider (Path pathToData) ( byte colliderData = readByteData (pathToData) ; String textData = convertBytesToSymbols (colliderataDataData) ; print = File saveDataDataData) ; fileWithData) ) ; ) verejný bajt readByteData (Cesta pathToData) ( // načíta údaje v bajtoch) public String convertBytesToSymbols (byte colliderDataInBytes) ( ) public File saveToFile (String colliderData) ( ) public void printColliderData (File fileWithColliderData) ( // tlač údajov zo súboru) ) Ako si však pamätáte z prednášky o rozhraniach, používateľ získa prístup len ku konečnému rozhraniu. A naše 4 metódy nie sú jeho súčasťou. Oni pomocný: vytvorili sme ich preto, aby sme zlepšili čitateľnosť kódu a nie aby sme dali štyri rôzne úlohy do jednej metódy. Používateľovi nemusíte poskytnúť prístup k týmto metódam. Ak má používateľ pri práci s urýchľovačom prístup k metóde convertBytesToSymbols(), s najväčšou pravdepodobnosťou jednoducho nerozumie, čo je táto metóda a prečo je potrebná. Aké bajty sa konvertujú? Odkiaľ prišli? Prečo ich previesť na text? Logika, ktorá sa vykonáva v tejto metóde, nie je súčasťou používateľského rozhrania. Súčasťou rozhrania je iba metóda readDataFromCollider(). Čo robiť s týmito štyrmi „vnútornými“ metódami? Správny! Obmedzte k nim prístup pomocou súkromného modifikátora. Svoju prácu tak môžu bezpečne vykonávať vo vnútri triedy a nezavádzať používateľa, ktorý nepotrebuje logiku každého z nich zvlášť. public class ColliderUtil ( public void readDataFromCollider (Path pathToData) ( bajt colliderData = readByteData (pathToData) ; String textData = convertBytesToSymbols (colliderData) ; File fileWithData = saveToFile (textData) (Dataata printToData) cesta Data (Data printToColli) // načíta údaje v bajtoch) private String convertBytesToSymbols (byte colliderDataInBytes) ( // prevod bajtov na znaky) private File saveToFile(String colliderData) ( // uloženie načítaných údajov do súboru) private void printColliderData(Súbor súboruWithColliderData)( // tlač údajov zo súboru } }

chránený modifikátor

Ďalší najviac obmedzujúci modifikátor prístupu je chránený.
Polia a metódy označené modifikátorom chráneného prístupu budú viditeľné:
  • v rámci všetkých tried, ktoré sú v rovnakom balíku ako naša;
  • v rámci všetkých tried, ktoré dedia od našej triedy.
Je ťažké si predstaviť, kedy to môže byť potrebné. Nečudujte sa: chránených má oveľa menej použití ako súkromné ​​a sú špecifické. Predstavte si, že máme abstraktnú triedu AbstractSecretAgent , označujúcu tajného agenta nejakej špeciálnej služby, ako aj balík top_secret , ktorý obsahuje túto triedu a jej potomkov. Z nej sa dedia konkrétne triedy - FBISecretAgent , MI6SecretAgent , MossadSecretAgent atď. Vo vnútri abstraktnej triedy chceme implementovať počítadlo agentov. Keď sa niekde v programe vytvorí nový objekt agenta, zvýši sa. balíček top_secret; public abstract class AbstractSecretAgent ( public static int agentCount = 0 ; ) Ale naši agenti sú tajní! O ich počte by teda nemali vedieť len oni a nikto iný. Chránený modifikátor môžeme jednoducho pridať do poľa agentCount a potom môžu získať svoju hodnotu buď objekty iných tried tajných agentov, alebo tie triedy, ktoré sa nachádzajú v našom „tajnom“ balíku top_secret. verejná abstraktná trieda AbstractSecretAgent ( protected static int agentCount = 0 ; ) Pre takéto špecifické úlohy je potrebný chránený modifikátor :)

viditeľný modifikátor balíka

Ďalej v zozname je predvolený modifikátor alebo, ako sa tiež nazýva, balík viditeľný . Nie je označený kľúčovým slovom, pretože je štandardne nastavený v jazyku Java pre všetky polia a metódy. Ak do kódu napíšete - int x = 10 ... premenná x bude mať rovnaký viditeľný prístup. Je ľahké si zapamätať, čo robí. V skutočnosti je predvolené = chránené -dedenie :) Prípady jeho použitia sú obmedzené, ako napríklad chránený modifikátor. Predvolený prístup sa najčastejšie používa v balíku, kde sú niektoré pomocné triedy, ktoré neimplementujú funkčnosť všetkých ostatných tried v tomto balíku. Vezmime si príklad. Predstavte si, že máme balík služby". V jeho vnútri sú rôzne triedy, ktoré pracujú s databázou. Napríklad existuje trieda UserService, ktorá číta používateľské údaje z databázy, trieda CarService, ktorá číta údaje o aute z rovnakej databázy a ďalšie triedy, z ktorých každá pracuje s vlastným typom objektov a načítava o nich údaje z databázy. . balíkové služby; verejná trieda UserService ( ) balíkové služby; public class CarService ( ) Ľahko sa však môže stať, že údaje v databáze sú v jednom formáte, no potrebujeme ich v inom. Predstavte si, že dátum narodenia používateľa je v databáze uložený vo formáte ČASOVÁ ZNÁMKA S ČASOVÝM PÁSOM... 2014 - 04 - 04 20 : 32 : 59,390583 + 02 ...potrebujeme namiesto toho najjednoduchší objekt - java.util. Dátum . Na tento účel môžeme v balíku služieb vytvoriť špeciálnu triedu Mapper. Bude zodpovedný za konverziu údajov z databázy do objektov Java, ktoré poznáme. Jednoduchá pomocná trieda. Všetky triedy zvyčajne vytvárame ako verejnú triedu ClassName , ale nie je to povinné. Našu pomocnú triedu môžeme deklarovať jednoducho ako triedu Mapper . V tomto prípade stále robí svoju prácu, ale nie je viditeľná pre nikoho mimo balíka služieb! balíkové služby; balíkové služby triedy Mapper(); public class CarService (Maper mapper; ) A toto je v podstate správna logika: prečo by niekto mimo balíka videl pomocnú triedu, ktorá funguje len s triedami v tom istom balíku?

verejný modifikátor

A v neposlednom rade verejný modifikátor! Stretli ste ho prvý deň v JavaRush, kde ste prvýkrát v živote spustili verejný statický void main (String args).
Teraz, keď ste si preštudovali prednášky o rozhraniach, je vám jeho účel jasný :) Verejné bolo predsa vytvorené preto, aby používateľom niečo dalo. Napríklad rozhranie vášho programu. Povedzme, že ste napísali prekladateľský program, ktorý dokáže preložiť ruský text do angličtiny. Vytvorili ste metódu translate(String textInRussian), v ktorej je implementovaná potrebná logika. Túto metódu ste označili slovom public a teraz sa stane súčasťou rozhrania: public class Translator ( public String translate (String textInRussian) ( // preloží text z ruštiny do angličtiny) ) Toto volanie metódy môžete priradiť k tlačidlu „preložiť“ na obrazovke programu – a je to! Môže ho použiť ktokoľvek. Časti kódu označené modifikátorom public sú určené pre koncového používateľa. Aby som uviedol príklad zo života, súkromné ​​sú všetky procesy, ktoré prebiehajú vo vnútri televízora, keď funguje, a verejné sú tlačidlá na diaľkovom ovládači televízora, pomocou ktorých ho môže používateľ ovládať. Zároveň nemusí vedieť, ako je televízor usporiadaný a ako funguje. Konzola je sada verejných metód: on() , off() , nextChannel() , previousChannel() , raiseVolume() , reductionVolume() atď.

Načítava...
Hore