Koks skirtumas tarp viešojo, saugaus, partijų ir privačių „Java“?

„Java“ yra aiškios taisyklės, kada naudoti kiekvieną prieigos modifikatorių, būtent numatytąjį (privatų paketą), public , protected ir private , padarant class ir interface ir apdorojant paveldėjimu?

2722
18 окт. nustatyti intrepioną 18 okt. 2008-10-18 22:53 '08 10:53 val. 2008-10-18 22:53
@ 27 atsakymai

Oficialus vadovas gali jums padėti.

 │ C │ P │ Pogrupis │ W poklasis │ l │ a │ (tas pats pkg) │ (diff pkg) │ o │ │ a │ c │ │ │ r │ │ s │ k │ │ │ l │ │ s │ a │ │ │ d │ │ │ g │ │ │ │ │ e │ │ │ │ ────────────┼─── + + ───┼──────────┼──────────┼───┼ viešas │ + │ + │ + │ + │ + │ ────────────┼───────┼──────────┼──────────┼───┼ saugoma │ + │ + │ + │ + │ │ ────────────┼───────┼──────────┼──────────┼───┼ be modifikatoriaus │ + │ + │ + │ │ │ ────────────┼───────┼──────────┼──────────┼───┼ privatus │ + │ │ │ │ │  +: prieinama tuščia: nepasiekiama
4983
18 окт. David S. Oct. Atsakymas 2008-10-18 22:57 '08, 10:57 pm 2008-10-18 22:57

(Caveat: aš nesu „Java“ programuotojas, aš esu „Perl“ programuotojas. Perl neturi oficialių apsaugos, galbūt todėl gerai suprantu problemą :))

Privatus

Ar manote, kad tai mato tik klasė , kurioje ji yra paskelbta.

Asmeninis paketas

Jis gali būti rodomas ir naudojamas tik pakuotėje , kurioje jis buvo paskelbtas. Tai yra numatytoji vertė „Java“ (kai kurie žmonės mano, kad klaida).

Apsaugota

Asmeninį + paketą gali matyti poklasiai arba paketo narys.

Vieša

Kiekvienas gali jį pamatyti.

border=0

Paskelbta

Matoma už kodo, kurį kontroliuoju. (Nors tai nėra „Java“ sintaksė, tai svarbu šiai diskusijai).

C ++ apibrėžia papildomą lygį, vadinamą „draugu“, ir kuo mažiau žinote, tuo geriau.

Kada turėtumėte naudoti ką? Visa idėja yra kapsuliavimas, kad būtų galima slėpti informaciją. Kiek įmanoma, norite paslėpti informaciją apie tai, kaip kažkas daroma iš jūsų naudotojų. Kodėl? Nes tada jūs galite juos vėliau pakeisti ir nepažeisti. Tai leidžia optimizuoti, reorganizuoti, pertvarkyti ir ištaisyti klaidas, nebijodami, kad kas nors naudos šį kodą, kurį ką tik peržiūrėjote.

Taigi nykščio taisyklė yra, kad viskas būtų matoma taip, kaip turėtų būti. Pradėkite nuo privačių ir tiesiog pridėkite daugiau matomumo, kiek reikia. Paskelbkite tik tai, kas būtina naudotojui žinoti, kiekviena jūsų viešai skelbiama detalė sukuria sugebėjimą pertvarkyti sistemą.

Jei norite, kad vartotojai galėtų pritaikyti elgesį, o ne atvirus ežerus, kad jie galėtų juos iš naujo apibrėžti, dažnai būna geriau perkelti šiuos vidus į objektą ir padaryti šią sąsają viešai prieinamą. Taigi jie gali tiesiog prijungti naują objektą. Pvz., Jei rašote CD grotuvą ir norite, kad būtų galima sukonfigūruoti „eiti ieškoti informacijos apie šį kompaktinį diską“, o ne skelbti šiuos metodus, įtraukite visas šias funkcijas į savo objektą ir atlikite getter / setter objektą apskritai prieinama, todėl gaila atskleisti savo vidų, skatina gerą sudėtį ir problemų atskyrimą.

Asmeniškai aš tik palieku „privatų“ ir „viešą“. Daugelis OO kalbų turi tai. „Saugoma“ gali būti naudinga, bet tai tikrai apgauti. Kai tik sąsaja yra daugiau nei privati, ji yra nevaldoma, ir jūs turite ieškoti kodo, kurį gali rasti kiti žmonės.

Čia atsiranda „leidybos“ idėja. Pakeitus sąsają (refactoring) reikia rasti visą kodą, kuris jį naudoja, ir jį pakeisti. Jei sąsaja yra privati, problema nėra. Jei jis yra apsaugotas, turite rasti visus savo poklasius. Jei jis yra viešas, turite rasti visą kodą, kurį naudoja jūsų kodas. Kartais tai įmanoma, pavyzdžiui, jei dirbate su įmonės kodu, kuris naudojamas tik vidiniam naudojimui, nesvarbu, ar sąsaja yra atvira. Visą kodą galite išgauti iš įmonės saugyklos. Bet jei sąsaja yra „paskelbta“, jei yra kodas, kuris jį naudoja už jūsų kontrolės ribų, tada būsite uždaryti. Turite palaikyti šią sąsają arba rizikos pažeidimo kodą. Net saugios sąsajos gali būti laikomos paskelbtomis (todėl nerimauju dėl saugumo).

Daugelis kalbų viešosios / saugomos / privačios hierarchinės prigimties yra pernelyg ribojančios ir nesuderinamos su tikrove. Šiuo tikslu egzistuoja klasės sąvoka, tačiau tai yra kitoks šou.

397
19 окт. Schwern atsakymas, pateiktas spalio 19 d 2008-10-19 00:17 '08 0:17 2008-10-19 00:17

Čia yra geriausia lentelės versija. (Ateityje yra modulių stulpelis.)

2019

10 нояб. aioobe lapkričio 10 d 2015-11-10 13:27 '15, 13:27, 2015-11-10 13:27
  | highest precedence <---------> lowest precedence *———————————————+———————————————+———————————+———————————————+——————— \ xCanBeSeenBy | this | any class | this subclass | any \__________ | class | in same | in another | class \ | nonsubbed | package | package | Modifier of x \ | | | | ————————————————*———————————————+———————————+———————————————+——————— public | ✔ | ✔ | ✔ | ✔ ————————————————+———————————————+———————————+———————————————+——————— protected | ✔ | ✔ | ✔ | ✘ ————————————————+———————————————+———————————+———————————————+——————— package-private | | | | (no modifier) | ✔ | ✔ | ✘ | ✘ ————————————————+———————————————+———————————+———————————————+——————— private | ✔ | ✘ | ✘ | ✘ 
177
10 янв. Atsakymas, kurį pateikė Abdull, sausio 10 2013-01-10 00:42 '13 prie 0:42 2013-01-10 00:42

Paprasta taisyklė. Pradėkite skelbdami visus asmeninius. Ir tada pažanga visuomenės atžvilgiu, kai atsiranda poreikis, ir dizainas tai pateisina.

Eksponuojant eksponentus paklauskite savęs, ar pasirinkote, ar pasirinkote abstrakciją. Pirmasis yra tas, kurį norite išvengti, nes jis per daug priklausys nuo faktinio pateikimo, o ne nuo jo stebimo elgesio.

Paprastai aš stengiuosi išvengti metodo įgyvendinimo nepaisymo subklasuojant; tai pernelyg lengva nuskęsti logiką. Jei ketinate jį panaikinti, paskelbite abstrakčius apsaugotus metodus.

Taip pat naudokite „@Orride“ komentarą, kai jūs iš naujo nustatote, kad reorganizuojant dalykai nesulūžtų.

142
18 окт. Atsakymą pateikė John Nilsson spalio 18 d 2008-10-18 23:00 '08 23:00 val. 2008-10-18 23:00

Tai iš tikrųjų yra šiek tiek sudėtingesnis už paprastus tinklus. Tinklelis rodo, ar prieiga yra leidžiama, bet kas tiksliai yra prieiga? Be to, prieigos lygiai sąveikauja su įdėtomis klasėmis ir paveldėjimu sudėtingais būdais.

Numatytoji prieiga (nurodoma, kai nėra raktinio žodžio) taip pat vadinama paketu-privačiu . Išimtis: sąsajoje nė vienas modifikatorius reiškia atvirą prieigą; draudžiami nekomerciniai modifikatoriai. Nuolatinės konstantos visada yra viešos.

Santrauka

Ar leidžiama naudotis nariu su nurodytu prieigos nustatymu?

  • Narys private : tik tuo atveju, jei narys yra apibrėžtas toje pačioje klasėje kaip ir skambinimo kodas.
  • Vartotojas yra uždaras paketas: tik tuo atveju, jei skambinimo kodas yra nario viduje, kuris nedelsiant turi paketą.
  • Narys protected : tas pats paketas arba, jei narys yra apibrėžtas klasės, kurioje yra skambinimo kodas, klasėje.
  • Narys: Taip.

Kokie prieigos specifikai susiję

Vietiniai kintamieji ir formalūs parametrai negali priimti prieigos specifikų. Kadangi jie yra neprieinami iš išorės pagal regėjimo lauko nustatymo taisykles, jie iš tikrųjų yra uždaryti.

Viršutinėje srityje esančioms klasėms leidžiama naudoti tik public ir privačius paketus. Daroma prielaida, kad šis dizaino pasirinkimas priklauso nuo to, kad protected ir private paketas bus nereikalingas (paketinio paveldo nėra).

Visi prieigos atributai galimi klasės nariams (konstruktoriams, metodams ir statiniams nario funkcijoms, įdėtoms klasėms).

Susiję: „ Java“ klasės prieinamumas

Užsakymas

Prieigos specifikacijas galima griežtai užsisakyti.

viešas> apsaugotas> paketas-privatus> privatus

tai reiškia, kad public suteikia didžiausią prieigą, mažiausiai private . Bet kokia privataus nario turima nuoroda galioja ir asmeninio paketo nariui; bet kokia nuoroda į privačiojo paketo narį galioja saugomam nariui ir pan. (Vienos pakuotės prieigos prie saugomų narių suteikimas kitoms klasėms buvo laikoma klaida.)

Pastabos

  • Klasės metodams leidžiama patekti į kitų tos pačios klasės objektų privačius narius. Tiksliau, C klasės metodas gali pasiekti privačius bet kurio C klasės subjekto C grupės narius. (Palyginkite su „Scala“, kuri ją palaiko naudodama private[this] .)
  • Norint sukurti objektą, jums reikia prieigos prie konstruktoriaus. Taigi, jei visi konstruktoriai yra privatūs, klasė gali būti sukurta tik pagal kodą, kuris gyvena klasėje (paprastai statiniai gamyklos metodai arba statiniai kintamieji). Panašiai ir statybininkams, privatiems ir privatiems asmenims, arba saugomiems.
    • Tik privačių konstruktorių buvimas taip pat reiškia, kad klasė negali būti subklasifikuota išoriškai, nes „Java“ reikalauja, kad poklasio konstruktoriai netiesiogiai arba aiškiai kviestų superklasės konstruktorių. (Tačiau jame gali būti įslaptinta klasė, kurią jis subklasuoja.)

Vidinės klasės

Taip pat reikia atsižvelgti į įdėtus regionus, pvz., Vidines klases. Sudėtingumo pavyzdys yra tai, kad vidinės klasės turi narių, kurie patys gali naudoti prieigos modifikatorius. Taigi, jūs galite turėti privačią vidinę klasę su atviru nariu; gali naudotis nariu? (Žr. Žemiau.) Bendroji taisyklė - pažvelgti į taikymo sritį ir pagalvoti apie tai, ar galite pasiekti kiekvieną lygį.

Tačiau tai yra gana sunku, o išsami informacija pateikiama „Java“ kalbos specifikacijoje . (Taip, praeityje buvo kompiliatoriaus klaidų.)

Norėdami suprasti, kaip jie bendrauja, apsvarstykite šį pavyzdį. Galbūt privačių vidinių klasių „nutekėjimas“; Tai paprastai yra įspėjimas:

 class Test { public static void main(final String ... args) { System.out.println(Example.leakPrivateClass()); // OK Example.leakPrivateClass().secretMethod(); // error } } class Example { private static class NestedClass { public void secretMethod() { System.out.println("Hello"); } } public static NestedClass leakPrivateClass() { return new NestedClass(); } } 

Kompiliatoriaus išvestis:

 Test.java:4: secretMethod() in Example.NestedClass is defined in an inaccessible class or interface Example.leakPrivateClass().secretMethod(); // error ^ 1 error 

Kai kurie susiję klausimai:

99
13 сент. Atsakymas pateikiamas Mechaninė sraigė rugsėjo 13 d 2012-09-13 10:38 '12 10:38 am 2012-09-13 10:38

Kaip taisyklė:

  • privatus : klasė.
  • numatytasis (arba paketinis-privatus): paketo sritis.
  • apsaugota : paketo apimtis + vaikas (pvz., paketas, bet mes galime subklasuoti jį iš skirtingų paketų). Apsaugotas modifikatorius visada išsaugo tėvų ir vaikų santykius.
  • visuomenė : visur.

Todėl, jei prieigos teises skirstome į tris teises:

  • (D) tiesioginis (skambinkite iš tos pačios klasės metodo).
  • (R) (metodas skambinti naudojant klasės nuorodą arba „taškų“ sintaksę).
  • (I) neveiklumas (per poklasius).

tada mes turime šią paprastą lentelę:

 +—-———————————————+————————————+———————————+ | | Same | Different | | | Package | Packages | +—————————————————+————————————+———————————+ | private | D | | +—————————————————+————————————+———————————+ | package-private | | | | (no modifier) | DRI | | +—————————————————+————————————+———————————+ | protected | DRI | I | +—————————————————+————————————+———————————+ | public | DRI | RI | +—————————————————+————————————+———————————+ 
72
18 дек. Atsakymą pateikė 18 d. 2012-12-18 21:01 '12 9:01 val. 2012-12-18 21:01

Labai trumpai

  • public : prieinama visur.
  • protected : prieiga prie klasės toje pačioje pakuotėje ir poklasiai, esantys bet kuriame pakete.
  • pagal nutylėjimą (nenurodytas modifikatorius): prieinama pagal to paties paketo klases.
  • private : galima tik vienoje klasėje.
46
27 окт. atsakymą pateikė Ravi spalio 27 d. 2012-10-27 20:49 '12, 08:49 PM 2012-10-27 20:49

Labiausiai nesuprastas „Java“ prieigos modifikatorius yra protected . Mes žinome, kad jis atrodo kaip numatytasis modifikatorius su viena išimtimi, kuria gali matyti poklasiai. Bet kaip? Štai pavyzdys, kurį tikiuosi išvalyti:

  • Tarkime, mes turime 2 klases; Father ir Son , kiekvienas savo pakete:

     package fatherpackage; public class Father { } ------------------------------------------- package sonpackage; public class Son extends Father { } 
  • Pridėkite apsaugotą foo() metodą Father .

     package fatherpackage; public class Father { protected void foo(){} } 
  • foo() metodas gali būti vadinamas keturiais kontekstais:

    • Klasėje, kuri yra toje pačioje pakuotėje, kurioje foo() apibrėžta foo() :

       package fatherpackage; public class SomeClass { public void someMethod(Father f, Son s) { f.foo(); s.foo(); } } 
    • Per šį pokalbio pokalbio pokalbį su this arba super :

       package sonpackage; public class Son extends Father { public void sonMethod() { this.foo(); super.foo(); } } 
    • Nuorodoje, kurios tipas yra ta pati klasė:

       package fatherpackage; public class Father { public void fatherMethod(Father f) { f.foo(); // valid even if foo() is private } } ------------------------------------------- package sonpackage; public class Son extends Father { public void sonMethod(Son s) { s.foo(); } } 
    • fatherpackage , kurios tipas yra patronuojanti klasė, ir yra pakuotės viduje, kuriame foo() apibrėžta foo() ( fatherpackage ) [Tai gali būti įtraukta į kontekstą. 1]:

       package fatherpackage; public class Son extends Father { public void sonMethod(Father f) { f.foo(); } } 
  • Netinkamos tokios situacijos.

    • fatherpackage , kurios tipas yra patronuojanti klasė, ir yra už paketo ribų, kur foo() apibrėžtas ( fatherpackage ):

       package sonpackage; public class Son extends Father { public void sonMethod(Father f) { f.foo(); // compilation error } } 
    • Pogrupis pakategorės pakete (pogrupis paveldi saugomus narius iš savo tėvų ir leidžia juos uždaryti ne poklasiams):

       package sonpackage; public class SomeClass { public void someMethod(Son s) throws Exception { s.foo(); // compilation error } } 
37
15 нояб. atsakymas duotas Eng.Fouad 15 nov. 2013-11-15 23:06 '13, 23:06 2013-11-15 23:06

Privatus

  • Metodai, kintamieji ir konstruktoriai

Metodai, kintamieji ir konstruktoriai, paskelbti privačiais, gali būti prieinami tik deklaruotoje klasėje.

  • Klasė ir sąsaja

Privatus modifikatorius yra labiausiai ribojantis prieigos lygis. Klasė ir sąsajos negali būti privačios.

Pastaba

Kintamieji, paskelbti privačiais, gali būti prieinami už klasės ribų, jei klasėje yra viešųjų getter metodų. Kintamieji, metodai ir konstruktoriai, paskelbti apsaugotais superklasėje, gali būti prieinami tik kito paketo poklasiams arba bet kuriai saugomų narių klasės pakuotės klasei. <h / ">

Apsaugota

  • Klasė ir sąsaja

Saugios prieigos modifikatorius negalima taikyti klasei ir sąsajoms.

Metodai, laukai gali būti paskelbti saugomais, tačiau sąsajos metodai ir laukai negali būti apsaugoti.

Pastaba

Apsaugota prieiga suteikia poklasiui galimybę naudoti pagalbinį metodą arba kintamąjį, neleidžiant nesusijusiai klasei ją naudoti.

<h / ">

Vieša

Klasė, metodas, konstruktorius, sąsaja ir tt, paskelbti viešais, gali būti pasiekiami iš bet kurios kitos klasės.

Todėl laukus, metodus, blokus, paskelbtus atviroje klasėje, galima pasiekti iš bet kurios klasės, priklausančios „Java Universe“.

  • Įvairūs paketai

Tačiau, jei atvira klasė, kurią bandome pasiekti, yra kitame pakete, tada viešoji klasė vis dar turi būti importuojama.

Dėl klasės paveldėjimo visi viešieji metodai ir klasės kintamieji paveldimi poklasiais.

<h / ">

Numatytasis - nėra raktinio žodžio:

Numatytasis prieigos modifikatorius reiškia, kad mes aiškiai nenurodome prieigos modifikatoriaus klasės, lauko, metodo ir kt.

  • Tos pačios pakuotės

Kintamasis arba metodas, deklaruotas be prieigos kontrolės modifikatoriaus, yra prieinamas bet kuriai kitai tos pačios pakuotės klasei. Sąsajos laukai yra netiesiogiai vieši statiniai, o sąsajoje esantys metodai yra vieši.

Pastaba

Negalime pakeisti statinių laukų. Jei bandote jį pakeisti, klaida nebus rodoma, tačiau ji neveikia, išskyrus mus.

Atsakymai į klausimus

Nuorodų nuorodos

http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html http://www.tutorialspoint.com/java/java_access_modifiers.htm

27
22 янв. Atsakymą pateikė Nambi sausio 22 d 2014-01-22 16:08 '14 at 16:08 2014-01-22 16:08

Privatus : ribota prieiga tik į klasę

Numatytasis (be modifikatoriaus) : ribota prieiga prie klasės ir paketo

Apsaugota : ribota prieiga prie klasės, paketo ir poklasių (tiek viduje, tiek išorėje)

Visuomenė : prieiga prie klasės, paketo (visų) ir poklasių ... Trumpai tariant, visur.

17
18 июня '14 в 10:13 2014-06-18 10:13 atsakymas pateikiamas samkit shah birželio 18 d. 14 val. 10:13 2014-06-18 10:13

Skirtumą galima rasti jau minėtose sąsajose, tačiau dažniausiai tai sumažinama iki „Mažiausių žinių principo“. Leisti tik minimalų matomumą, kurio reikia.

15
18 окт. Joe Phillips atsakymas 18 okt. 2008-10-18 23:00 '08 23:00 val. 2008-10-18 23:00

Prieigos modifikatoriai yra skirti apriboti prieigą keliais lygiais.

Leidinys :. Это в основном так же просто, как вы можете получить доступ из любого класса, будь то в одном пакете или нет.