ความแตกต่างระหว่าง public, protected, package-private และ private ใน Java คืออะไร?


3171

ใน Java จะมีกฎระเบียบที่ชัดเจนในเวลาที่จะใช้ในแต่ละของการปรับเปลี่ยนการเข้าถึงคือค่าเริ่มต้น (แพคเกจเอกชน) public, protectedและprivateในขณะที่ทำให้classและinterfaceและการจัดการกับมรดก?


161
privateซ่อนจากคลาสอื่นภายในแพ็คเกจ publicexposes ไปยังคลาสนอกแพคเกจ protectedเป็นรุ่นที่publicจำกัด เฉพาะคลาสย่อยเท่านั้น
Museful

87
@Tennenrishin - ไม่; ตรงกันข้ามกับ C ++ ใน Java protectedทำให้วิธีการนี้สามารถเข้าถึงได้จากแพ็คเกจทั้งหมด ความโง่เขลาในรูปแบบการแสดงผลของ Java protectedนี้แบ่งเป้าหมายของการ
Nicolas Barbulesco

35
@Nicolas protectedมันสามารถเข้าถึงได้จากแพคเกจทั้งหมดที่มีหรือไม่มี ในฐานะที่เป็นตัวดัดแปลงการเข้าถึงสิ่งที่protectedทำก็คือการเปิดเผยไปยังคลาสย่อยนอกแพ็คเกจ
Muse

15
@tennenrishin - นั่นคือสิ่งที่นิโคลัสพูด ... และคุณแค่ทำซ้ำตอนนี้ สิ่งที่คุณเดิมกล่าวคือการที่protected- และฉันพูด - 'เป็นรุ่นของประชาชนถูก จำกัด เพียงเพื่อ subclasses' ซึ่งไม่เป็นความจริงโดยเข้ารับการรักษาของคุณเองตั้งแต่การป้องกันยังช่วยให้การเข้าถึงผ่านแพคเกจทั้งหมด (เพราะฉะนั้นก็ไม่ได้จำกัด การเข้าถึง subclasses )
luis.espinal

10
ฉันเห็นด้วยกับ Nicolas ด้วยว่าโหมดการเข้าถึงที่ได้รับการป้องกันใน Java นั้นเป็นเรื่องงี่เง่า สิ่งที่เกิดขึ้นคือ Java ทำให้โครงข่ายตัว จำกัด แนวนอน (ขัดแตะ) และตัว จำกัด การเข้าถึงแนวตั้ง ขอบเขตเริ่มต้นคือข้อ จำกัด แนวนอน / ขัดแตะด้วยตาข่ายเป็นแพคเกจ สาธารณะเป็นข้อ จำกัด ในแนวนอนที่ขัดแตะเป็นทั้งโลก การป้องกันส่วนบุคคลและ (C ++) เป็นแนวตั้ง มันคงจะดีกว่านี้ถ้าเรามีการเข้าถึงแบบ cross-cut พูดprotected-packageสำหรับกรณีที่หาได้ยากที่เราต้องการจริง ๆ ปล่อยprotectedให้เทียบเท่ากับรุ่น C ++ ที่ได้รับการป้องกัน
luis.espinal

คำตอบ:


5637

บทแนะนำอย่างเป็นทางการอาจเป็นประโยชน์สำหรับคุณ

______________________________________________________________
| │คลาส│แพ็คเกจ│คลาสย่อย│คลาสย่อย│โลก |
| │││ (pkg เดียวกัน) │ (diff pkg) │ |
| ───────────┼───────┼─────────┼──────────┼──────── ──┼──────── |
| สาธารณะ│ + │ + │ + │ + │ + | 
| ───────────┼───────┼─────────┼──────────┼──────── ──┼──────── |
| ป้องกัน│ + │ + │ + │ + │ | 
| ───────────┼───────┼─────────┼──────────┼──────── ──┼──────── |
| ไม่มีตัวดัดแปลง│ + │ + │ + ││ | 
| ───────────┼───────┼─────────┼──────────┼──────── ──┼──────── |
| ส่วนตัว│ + ││││ |
| ___________ | _______ | _________ | __________ | __________ | ________ |
 +: ช่องว่างที่สามารถเข้าถึงได้: ไม่สามารถเข้าถึงได้

5
ตารางข้างต้นไม่ถูกต้องเนื่องจากprivateสมาชิกสามารถดู / ใช้งานโดยวิธีการคลาส / สแตติกใด ๆ ในไฟล์ต้นฉบับเดียวกัน
Usagi Miyamoto

5
สมาชิกที่ได้รับการป้องกันสามารถเข้าถึงได้จากคลาสย่อยของแพ็คเกจเดียวกัน แต่ไม่ใช่คลาสย่อยจากแพ็คเกจอื่น ควรมีการแก้ไขในตารางด้านบน
นิ

2
โลกอยู่ในโครงการของคุณ ฉันควรอธิบายเพิ่มเติม ห้องสมุดอยู่ในโครงการของคุณและหากคุณกำลังสร้างห้องสมุดพวกเขาจะเปิดเผยชั้นเรียนสาธารณะและวิธีการเหล่านี้เช่นกัน ดังนั้นการบอกว่าภายในโครงการของคุณจะปิดสักหน่อย "ทุกสิ่งที่ใช้มัน" เป็นคำอธิบายที่ดีกว่า
adprocas

3
ตัวอย่างเช่นถ้าฉันมีMyClassและฉันทำฉันจะมีการเข้าถึงวิธีการป้องกันและส่วนกลางทั้งหมดและคุณสมบัติจากภายในAnotherClass extends MyClass AnotherClassถ้าฉันทำMyClass myClass = new MyClass();ในAnotherClassบาง - สมมติว่าสร้าง - ฉันจะมีเพียงการเข้าถึงวิธีการสาธารณะถ้ามันมีอยู่ในแพคเกจที่แตกต่างกัน โปรดทราบว่าถ้าฉันทำ= new MyClass() { @Override protected void protectedMethod() { //some logic } };มันปรากฏว่าฉันสามารถเข้าถึงวิธีการป้องกัน แต่ชนิดนี้เหมือนขยาย แต่ inline แทน
adprocas

3
แต่น่าเสียดายที่คำตอบนี้เป็นสิ่งที่ง่ายเกินไป ความเป็นจริงนั้นค่อนข้างซับซ้อนโดยเฉพาะอย่างยิ่งเมื่อคุณพิจารณาprotected(ซึ่งจริงๆแล้วเป็นตัวดัดแปลงการเข้าถึงยากที่จะเข้าใจอย่างสมบูรณ์ - คนส่วนใหญ่ที่คิดว่าพวกเขารู้ว่าอะไรที่protectedไม่ได้หมายถึงจริงๆ) ยังเป็นโบฮีเมียนชี้ให้เห็นก็ไม่ได้ตอบคำถาม - มันบอกว่าไม่มีอะไรเกี่ยวกับเมื่อใช้ปรับปรุงการเข้าถึงแต่ละ ในความคิดของคำตอบนี้ไม่ได้ค่อนข้างมากพอที่ดีที่จะ downvote แต่ใกล้ แต่มีผู้โหวตเกิน 4,000 คน มันเกิดขึ้นได้อย่างไร?
Dawood ibn Kareem

483

(Caveat: ฉันไม่ใช่โปรแกรมเมอร์ Java, ฉันเป็นโปรแกรมเมอร์ Perl. Perl ไม่มีการป้องกันที่เป็นทางการซึ่งบางทีทำไมฉันเข้าใจปัญหาได้ดี :))

เอกชน

เช่นเดียวกับที่คุณคิดว่ามีเพียงคลาสที่มีการประกาศเท่านั้นที่สามารถเห็นได้

แพ็คเกจส่วนตัว

สามารถมองเห็นและใช้งานได้โดยแพ็คเกจที่ประกาศเท่านั้น นี่เป็นค่าเริ่มต้นใน Java (ซึ่งบางคนเห็นว่าเป็นความผิดพลาด)

มีการป้องกัน

แพ็คเกจไพรเวต + สามารถดูได้โดยคลาสย่อยหรือสมาชิกแพ็กเกจ

สาธารณะ

ทุกคนสามารถเห็นมัน

การตีพิมพ์

มองเห็นได้นอกโค้ดที่ฉันควบคุม (แม้ว่าไม่ใช่ไวยากรณ์ของ Java มันเป็นสิ่งสำคัญสำหรับการสนทนานี้)

C ++ กำหนดระดับเพิ่มเติมที่เรียกว่า "เพื่อน" และยิ่งคุณรู้น้อยเท่าไหร่ก็ยิ่งดีเท่านั้น

คุณควรใช้อะไรเมื่อไหร่ แนวคิดทั้งหมดคือการห่อหุ้มเพื่อซ่อนข้อมูล คุณต้องการซ่อนรายละเอียดของสิ่งที่ผู้ใช้ของคุณทำมากที่สุดเท่าที่จะทำได้ ทำไม? เพราะจากนั้นคุณสามารถเปลี่ยนพวกเขาในภายหลังและไม่ทำลายรหัสของใคร สิ่งนี้ช่วยให้คุณสามารถปรับแต่งสร้างใหม่ออกแบบและแก้ไขข้อบกพร่องโดยไม่ต้องกังวลว่ามีคนใช้รหัสนั้นที่คุณเพิ่งแก้ไข

ดังนั้นกฎของหัวแม่มือคือการทำให้สิ่งที่มองเห็นได้เท่าที่พวกเขาจะต้องเป็น เริ่มต้นด้วยส่วนตัวและเพิ่มการมองเห็นได้ตามต้องการเท่านั้น เปิดเผยต่อสาธารณะในสิ่งที่จำเป็นอย่างยิ่งที่ผู้ใช้จะต้องรู้ทุกรายละเอียดที่คุณทำให้เป็นตะคริวสาธารณะคือความสามารถของคุณในการออกแบบระบบใหม่

หากคุณต้องการให้ผู้ใช้สามารถปรับแต่งพฤติกรรมได้แทนที่จะทำให้ผู้ใช้ภายในเป็นแบบสาธารณะเพื่อให้สามารถแทนที่พวกเขาได้มักเป็นความคิดที่ดีที่จะผลักความกล้าเข้าไปในวัตถุและทำให้ส่วนต่อประสานนั้นเป็นแบบสาธารณะ ด้วยวิธีนี้พวกเขาสามารถเสียบวัตถุใหม่ ตัวอย่างเช่นหากคุณกำลังเขียนเครื่องเล่นซีดีและต้องการบิต "ไปหาข้อมูลเกี่ยวกับซีดีนี้" ที่ปรับแต่งได้แทนที่จะทำให้วิธีการเหล่านั้นเป็นแบบสาธารณะคุณจะต้องใส่ฟังก์ชั่นทั้งหมดนั้นเป็นวัตถุของตัวเองและทำให้วัตถุของคุณเป็นสาธารณะ . ด้วยวิธีนี้จะตระหนี่เกี่ยวกับการเปิดเผยความกล้าของคุณส่งเสริมองค์ประกอบที่ดีและการแยกความกังวล

ส่วนตัวแล้วฉันติดกับ "ส่วนตัว" และ "สาธารณะ" ภาษา OO จำนวนมากมีเพียงแค่นั้น "ป้องกัน" อาจมีประโยชน์ แต่จริงๆแล้วมันโกง เมื่ออินเทอร์เฟซเป็นมากกว่าส่วนตัวมันอยู่นอกเหนือการควบคุมของคุณและคุณต้องมองหารหัสของผู้อื่นเพื่อค้นหาการใช้งาน

นี่คือที่ความคิดของ "เผยแพร่" เข้ามาการเปลี่ยนอินเทอร์เฟซ (refactoring มัน) ต้องการให้คุณค้นหารหัสทั้งหมดที่ใช้งานและเปลี่ยนที่เกินไป หากอินเตอร์เฟสเป็นส่วนตัวก็ไม่มีปัญหา หากได้รับการป้องกันคุณจะต้องไปหาคลาสย่อยทั้งหมดของคุณ หากเป็นสาธารณะคุณต้องไปหารหัสทั้งหมดที่ใช้รหัสของคุณ บางครั้งสิ่งนี้เป็นไปได้เช่นถ้าคุณกำลังทำงานกับรหัส บริษัท ที่ใช้ภายในเท่านั้นไม่สำคัญว่าอินเทอร์เฟซแบบสาธารณะ คุณสามารถคว้ารหัสทั้งหมดออกจากที่เก็บขององค์กร แต่ถ้าอินเทอร์เฟซ "เผยแพร่" หากมีรหัสที่ใช้อยู่นอกการควบคุมของคุณแสดงว่าคุณถูกซ่อน คุณต้องรองรับส่วนต่อประสานนั้นหรือรหัสที่มีความเสี่ยง แม้กระทั่งอินเทอร์เฟซที่ได้รับการป้องกันก็ยังสามารถพิจารณาเผยแพร่ได้ (ซึ่งเป็นสาเหตุที่ฉันไม่ '

หลายภาษาพบว่าลักษณะแบบลำดับชั้นของสาธารณะ / ป้องกัน / ส่วนตัวที่จะ จำกัด เกินไปและไม่สอดคล้องกับความเป็นจริง ด้วยเหตุนี้จึงมีแนวคิดของคลาสลักษณะแต่นั่นเป็นอีกรายการ


26
friends -> "ยิ่งคุณรู้น้อยเท่าไหร่ก็ยิ่งดี" ---> มันให้การมองเห็นที่เลือกได้ซึ่งยังดีกว่าแพ็คเกจความเป็นส่วนตัว ใน C ++ มันมีการใช้งานเพราะฟังก์ชั่นบางอย่างอาจไม่ใช่ฟังก์ชั่นสมาชิกและเพื่อน ๆ ก็ดีกว่าการเป็นแบบสาธารณะ แน่นอนว่าจะมีอันตรายจากการใช้ความคิดชั่วร้าย
เซบาสเตียนมัค

30
ควรสังเกตว่า "การป้องกัน" ใน C ++ มีความหมายที่แตกต่างกัน - วิธีการป้องกันนั้นมีความเป็นส่วนตัวอย่างมีประสิทธิภาพ แต่ยังสามารถเรียกได้จากคลาสที่สืบทอด (ตรงข้ามกับ Java ที่สามารถเรียกได้โดยคลาสใด ๆ ภายในแพ็คเกจเดียวกัน)
Rhys van der Waerden

9
@RhysvanderWaerden C # เหมือนกับ C ++ ในด้านนี้ ฉันคิดว่ามันค่อนข้างแปลกที่ Java ไม่อนุญาตให้ประกาศสมาชิกที่เข้าถึงคลาสย่อยได้ แต่ไม่ใช่แพคเกจทั้งหมด มันค่อนข้างจะคว่ำสำหรับฉัน - แพ็คเกจนั้นมีขอบเขตที่กว้างกว่าชั้นเรียนเด็ก!
Konrad Morawski

15
@KonradMorawski IMHO แพ็คเกจมีขอบเขตขนาดเล็กกว่าคลาสย่อย หากคุณยังไม่ได้ประกาศคลาสของคุณครั้งสุดท้ายผู้ใช้ควรจะสามารถคลาสย่อยได้ดังนั้นการป้องกันจาวาเป็นส่วนหนึ่งของอินเทอร์เฟซที่เผยแพร่ของคุณ OTOH แพคเกจได้รับการพัฒนาโดยนัยโดยองค์กรเดียว: เช่น com.mycompany.mypackage หากรหัสของคุณประกาศตัวเองในแพ็คเกจของฉันคุณจะประกาศตัวเองว่าเป็นส่วนหนึ่งขององค์กรของฉันดังนั้นเราจึงควรสื่อสารกัน ดังนั้นแพ็คเกจจะเผยแพร่ไปยังกลุ่มเป้าหมายขนาดเล็ก / ง่ายต่อการเข้าถึงผู้ชม (คนใน บริษัท ของฉัน) กว่าคลาสย่อย (คนที่ขยายวัตถุของฉัน) และนับเป็นทัศนวิสัยที่ต่ำกว่า
Eponymous

2
friendดีสำหรับการกำหนดความสัมพันธ์พิเศษระหว่างคลาส มันช่วยให้การห่อหุ้มที่เหนือกว่าในหลายกรณีเมื่อใช้อย่างถูกต้อง ตัวอย่างเช่นมันสามารถใช้โดยคลาสโรงงานที่มีสิทธิพิเศษเพื่อฉีดการพึ่งพาภายในเป็นชนิดที่สร้างขึ้น มันมีชื่อที่ไม่ดีเพราะคนที่ไม่ใส่ใจในการรักษารูปแบบวัตถุที่ออกแบบมาอย่างดีสามารถใช้งานในทางที่ผิดเพื่อลดภาระงานของพวกเขา
เดนนิส

434

นี่คือตารางเวอร์ชันที่ดีกว่าซึ่งรวมคอลัมน์สำหรับโมดูลด้วย

Java Access Modifiers

คำอธิบาย

  • ส่วนตัวของสมาชิก ( i) เป็นเพียงสามารถเข้าถึงได้ภายในระดับเดียวกับที่มันถูกประกาศ

  • สมาชิกที่ไม่มีตัวดัดแปลงการเข้าถึง ( j) สามารถเข้าถึงได้ภายในคลาสในแพ็คเกจเดียวกันเท่านั้น

  • การคุ้มครองสมาชิก ( k) สามารถเข้าถึงได้ภายในทุกชั้นในแพคเกจเดียวกันและภายใน subclasses ในแพคเกจอื่น ๆ

  • สาธารณะสมาชิก ( l) สามารถเข้าถึงได้ทุกชั้น (ถ้ามันอยู่ในโมดูลที่ไม่ได้ส่งออกแพคเกจที่มีการประกาศใน)


ตัวแก้ไขใดให้เลือก

การปรับเปลี่ยนการเข้าถึงเป็นเครื่องมือที่จะช่วยให้คุณสามารถป้องกันการทำลาย encapsulation ตั้งใจ(*) ถามตัวคุณเองว่าคุณต้องการให้สมาชิกเป็นสมาชิกภายในชั้นเรียนแพคเกจลำดับชั้นของชั้นหรือไม่ได้อยู่ภายในเลยและเลือกระดับการเข้าถึงตามความเหมาะสม

ตัวอย่าง:

  • เขตข้อมูลlong internalCounterควรจะเป็นส่วนตัวเนื่องจากมีความไม่แน่นอนและรายละเอียดการใช้งาน
  • คลาสที่ควรถูกสร้างอินสแตนซ์ในคลาสโรงงาน (ในแพ็คเกจเดียวกัน) ควรมีคอนสตรัคเตอร์ที่ จำกัด แพคเกจเนื่องจากไม่สามารถเรียกได้โดยตรงจากภายนอกแพ็คเกจ
  • void beforeRender()วิธีการภายในที่เรียกว่าถูกต้องก่อนเรนเดอร์และใช้เป็นตะขอในคลาสย่อยควรได้รับการปกป้อง
  • void saveGame(File dst)วิธีการที่ถูกเรียกจากรหัส GUI ที่ควรจะเป็นที่สาธารณะ

(*) การห่อหุ้มคืออะไรกันแน่?


11
แค่พูดว่า: มีคนมากมายที่มีปัญหากับการแยกสีแดง / เขียว ตารางที่ใช้โครงร่างสีแดง / เขียว (หรือสีเหลือง / ส้ม / ... ) ไม่ค่อยมีอะไร "ดีกว่า" ที่อะไร ;-)
GhostCat

1
@GhostCat ฉันไม่เห็นด้วย ฉันคิดว่าสีแดง / สีเขียวสอดคล้องกับสัญชาตญาณกับ "งาน" / "ไม่ทำงาน" สำหรับคนจำนวนมากนั่นคือดีกว่าทางเลือกอื่น ๆ
aioobe

8
colourblindawareness.org/colour-blindness/... ... 8% ของผู้ชายสีตาบอดสามารถแบ่งออกเป็นประมาณ deuteranopes 1%, 1% protanopes, 1% protanomalous และ5% deuteranomalous และในขณะที่ฉันเป็นหนึ่งใน 50% ของ 5% นั้นโปรดวางใจ: สีแดง / เขียวดูด
GhostCat

6
@GhostCat ตกลง .. เป็นส่วนใหญ่ของประชากรมากกว่าที่ฉันคาดไว้ ฉันอัพโหลดภาพในโปรแกรมจำลองการตาบอดสีนี้และทดสอบโหมดที่แตกต่างกันทั้งหมด แม้ในโหมด monochromacy / achromatopsia ความแตกต่างของสีก็สมเหตุสมผล คุณเห็นความแตกต่างหรือเครื่องจำลองปิดอยู่หรือไม่? (ฉันยังคงมีความเห็นว่าสีแดง / สีเขียวจะง่ายมากสำหรับการมองเห็นสีคน.)
aioobe

3
ฉันเห็นความแตกต่าง แต่ฉันก็สามารถผ่านการทดสอบตาบอดสีครึ่งหนึ่งที่เราต้องทำในเยอรมนีสำหรับใบขับขี่ ;-) ... แต่ฉันคิดว่าตัวจำลองดังกล่าวนั้น "ดีพอ"
GhostCat

206
____________________________________________________________________
                | 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         |              |          |              |       
____________________________________________________________________

1
เป็นมูลค่าการใส่คำ - "ตัวแก้ไขที่ได้รับการป้องกันทำให้วัตถุพร้อมใช้งานในแพคเกจอื่น ๆ ในขณะที่ค่าเริ่มต้น / ไม่มีการแก้ไข จำกัด การเข้าถึงแพคเกจเดียวกัน"
vanguard69

2
@ vanguard69, โมดิprotectedฟายเออร์ทำให้สิ่งที่ทำเครื่องหมายไว้(คลาส, เมธอด, หรือฟิลด์) พร้อมใช้งานสำหรับคลาสอื่นในแพ็กเกจอื่นเท่านั้นถ้าหากกล่าวว่าคลาสอื่นเป็นคลาสย่อยของคลาสที่protected- สิ่งที่ถูกทำเครื่องหมายถูกประกาศ
Abdull

"nonsubbed"? "คลาสย่อยนี้ในแพ็คเกจอื่น" หรือไม่ ฮะ. ฉันคิดว่าฉันรู้จักชวา
sehe

@AlexanderFarber คุณปรับการตั้งค่าเบราว์เซอร์เฉพาะหรือไม่ นี้เป็นโครเมี่ยมของฉันตอนนี้และนี่คือFirefox
sehe

อืมเราจะยกเลิกการเปลี่ยนแปลงของฉันแล้ว
Alexander Farber

165

กฎง่าย ๆ เริ่มต้นด้วยการประกาศทุกอย่างส่วนตัว จากนั้นพัฒนาสู่สาธารณะเมื่อความต้องการเพิ่มขึ้นและออกแบบรับประกัน

เมื่อเปิดเผยให้สมาชิกถามตัวเองว่าคุณกำลังเปิดเผยตัวเลือกการเป็นตัวแทนหรือตัวเลือกที่เป็นนามธรรม สิ่งแรกคือสิ่งที่คุณต้องการหลีกเลี่ยงเพราะมันจะแนะนำการพึ่งพาที่มากเกินไปเกี่ยวกับการเป็นตัวแทนจริงแทนที่จะเป็นพฤติกรรมที่สังเกตได้

ตามกฎทั่วไปฉันพยายามหลีกเลี่ยงการแทนที่การใช้งานวิธีโดย subclassing; มันง่ายเกินไปที่จะทำให้เสียตรรกะ ประกาศวิธีการป้องกันแบบนามธรรมถ้าคุณตั้งใจจะให้มันถูกแทนที่

นอกจากนี้ให้ใช้คำอธิบายประกอบ @Override เมื่อแทนที่เพื่อป้องกันไม่ให้สิ่งแตกหักเมื่อคุณสร้างใหม่


3
@RuchirBaronia, "world" = รหัสทั้งหมดในแอปพลิเคชันโดยไม่คำนึงว่ามันอยู่ที่ไหน
Andrejs

116

จริงๆแล้วมันซับซ้อนกว่าการแสดงกริดแบบธรรมดาเล็กน้อย กริดจะบอกคุณว่าอนุญาตให้เข้าถึงได้หรือไม่ นอกจากนี้ระดับการเข้าถึงมีการโต้ตอบกับคลาสที่ซ้อนและการสืบทอดในวิธีที่ซับซ้อน

การเข้าถึง "เริ่มต้น" (ตามที่ระบุไว้กรณีที่ไม่มีคำหลัก) จะเรียกว่าแพคเกจและเอกชน ข้อยกเว้น: ในอินเทอร์เฟซไม่มีตัวดัดแปลงหมายถึงการเข้าถึงสาธารณะ ห้ามดัดแปลงอื่น ๆ นอกเหนือจากที่สาธารณะ ค่าคง Enum เป็นแบบสาธารณะเสมอ

สรุป

อนุญาตให้เข้าถึงสมาชิกที่มีตัวระบุการเข้าถึงนี้หรือไม่

  • สมาชิกคือprivate: เฉพาะสมาชิกที่กำหนดไว้ในคลาสเดียวกันกับรหัสการโทร
  • สมาชิกเป็นแพคเกจส่วนตัว: เฉพาะในกรณีที่รหัสการโทรอยู่ในแพ็คเกจที่แนบมาของสมาชิกทันที
  • สมาชิกคือprotected: แพคเกจเดียวกันหรือหากสมาชิกกำหนดไว้ในซูเปอร์คลาสของคลาสที่มีรหัสการโทร
  • สมาชิกคือpublic: ใช่

ตัวระบุการเข้าถึงที่ใช้กับอะไร

ตัวแปรโลคัลและพารามิเตอร์ทางการไม่สามารถใช้ตัวระบุการเข้าถึง เนื่องจากพวกเขาไม่สามารถเข้าถึงได้จากภายนอกตามกฎการกำหนดขอบเขตโดยเนื้อแท้พวกเขาจึงเป็นส่วนตัวอย่างมีประสิทธิภาพ

สำหรับคลาสที่อยู่ในขอบเขตด้านบนpublicจะอนุญาตให้ใช้เฉพาะแพคเกจส่วนตัวเท่านั้น ตัวเลือกการออกแบบนี้น่าจะเป็นเพราะprotectedและprivateจะซ้ำซ้อนในระดับแพ็คเกจ (ไม่มีการสืบทอดของแพ็คเกจ)

ตัวระบุการเข้าถึงทั้งหมดเป็นไปได้ในสมาชิกคลาส (ตัวสร้างวิธีการและฟังก์ชันสมาชิกแบบคงที่คลาสที่ซ้อนกัน)

ที่เกี่ยวข้อง: Java Class Accessibility

ใบสั่ง

ตัวระบุการเข้าถึงสามารถสั่งซื้อได้อย่างเคร่งครัด

สาธารณะ> ได้รับการป้องกัน> แพคเกจส่วนตัว> ส่วนตัว

ความหมายที่publicให้การเข้าถึงมากที่สุดprivateอย่างน้อย การอ้างอิงใด ๆ ที่เป็นไปได้สำหรับสมาชิกส่วนตัวนั้นใช้ได้สำหรับสมาชิกแพคเกจส่วนตัวเช่นกัน การอ้างอิงถึงสมาชิกแพคเกจส่วนตัวใด ๆ ที่ถูกต้องในสมาชิกที่ได้รับความคุ้มครองและอื่น ๆ (การเข้าถึงสมาชิกที่ได้รับความคุ้มครองในชั้นเรียนอื่น ๆ ในแพ็คเกจเดียวกันถือเป็นความผิดพลาด)

หมายเหตุ

  • วิธีการเรียนของจะได้รับอนุญาตให้สมาชิกส่วนตัวเข้าถึงวัตถุอื่น ๆ ของชั้นเรียนเดียวกัน แม่นยำยิ่งขึ้นวิธีการของคลาส C สามารถเข้าถึงสมาชิกส่วนตัวของ C บนวัตถุของคลาสย่อยใด ๆ ของ C. Java ไม่สนับสนุนการ จำกัด การเข้าถึงโดยอินสแตนซ์เฉพาะคลาสเท่านั้น (เปรียบเทียบกับ Scala ซึ่งรองรับการใช้งานprivate[this])
  • คุณต้องเข้าถึงตัวสร้างเพื่อสร้างวัตถุ ดังนั้นถ้าคอนสตรัคเตอร์ทั้งหมดเป็นแบบส่วนตัวคลาสสามารถสร้างได้โดยการใช้โค้ดในคลาสเท่านั้น ในทำนองเดียวกันสำหรับการก่อสร้างแพคเกจส่วนตัวหรือได้รับการคุ้มครอง
    • การมีคอนสตรัคเตอร์ส่วนตัวเท่านั้นหมายความว่าคลาสไม่สามารถคลาสย่อยภายนอกได้เนื่องจาก Java ต้องการคอนสตรัคเตอร์ของคลาสย่อยโดยปริยายหรือโดยปริยายเรียก superclass constructor (อย่างไรก็ตามสามารถมีคลาสที่ซ้อนกันซึ่งเป็นคลาสย่อย)

ชั้นใน

คุณต้องพิจารณาขอบเขตที่ซ้อนกันเช่นคลาสภายใน ตัวอย่างของความซับซ้อนคือคลาสภายในมีสมาชิกซึ่งสามารถใช้ตัวดัดแปลงการเข้าถึงได้ ดังนั้นคุณสามารถมีชั้นในส่วนตัวกับสมาชิกสาธารณะได้ สมาชิกสามารถเข้าถึงได้? (ดูด้านล่าง) กฎทั่วไปคือการดูขอบเขตและคิดซ้ำเพื่อดูว่าคุณสามารถเข้าถึงแต่ละระดับ

แต่นี้มีความซับซ้อนมากและสำหรับรายละเอียดเต็มปรึกษา Java Language ข้อกำหนด (ใช่มีคอมไพเลอร์บักในอดีต)

สำหรับรสชาติของวิธีการโต้ตอบเหล่านี้ให้พิจารณาตัวอย่างนี้ เป็นไปได้ที่จะ "รั่ว" ชั้นเรียนส่วนตัวภายใน; นี่เป็นคำเตือน:

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();
    }
}

คอมไพเลอร์เอาท์พุท:

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

บางคำถามที่เกี่ยวข้อง:


1
"โมดิฟายเออร์อื่น ๆ นอกเหนือจากสาธารณะเป็นสิ่งต้องห้าม" - ในฐานะของ Java 9, นี่ไม่ใช่กรณี: อินเตอร์เฟสสามารถมีวิธีส่วนตัวได้
MC Emperor

96

ตามกฎของหัวแม่มือ:

  • private: ขอบเขตของคลาส
  • default(หรือpackage-private): ขอบเขตของแพ็คเกจ
  • protected: package scope + child(เช่นแพคเกจ แต่เราสามารถ subclass ได้จากแพ็คเกจอื่น) ตัวดัดแปลงที่ได้รับการป้องกันจะรักษาความสัมพันธ์ "พาเรนต์ - ชาย" ไว้เสมอ
  • public: ทุกที่.

ดังนั้นหากเราแบ่งการเข้าถึงออกเป็นสามสิทธิ์:

  • (โดยตรง (เรียกใช้จากเมธอดภายในคลาสเดียวกันหรือผ่านทางไวยากรณ์ "this")
  • (R) eference (เรียกใช้เมธอดโดยใช้การอ้างอิงถึงคลาสหรือผ่านทางไวยากรณ์ "จุด")
  • (I) การสืบทอด (ผ่านคลาสย่อย)

จากนั้นเรามีตารางง่าย ๆ นี้:

+—-———————————————+————————————+———————————+
|                 |    Same    | Different |
|                 |   Package  | Packages  |
+—————————————————+————————————+———————————+
| private         |   D        |           |
+—————————————————+————————————+———————————+
| package-private |            |           |
| (no modifier)   |   D R I    |           |
+—————————————————+————————————+———————————+
| protected       |   D R I    |       I   |
+—————————————————+————————————+———————————+
| public          |   D R I    |    R  I   |
+—————————————————+————————————+———————————+

54

ในระยะสั้นมาก

  • public: เข้าถึงได้จากทุกที่
  • protected: สามารถเข้าถึงได้โดยคลาสของแพ็คเกจเดียวกันและคลาสย่อยที่อยู่ในแพ็คเกจใด ๆ
  • default (ไม่ได้ระบุตัวดัดแปลง): เข้าถึงได้โดยคลาสของแพ็คเกจเดียวกัน
  • private: สามารถเข้าถึงได้ภายในระดับเดียวกันเท่านั้น

48

ปรับการเข้าถึงเข้าใจผิดมากที่สุดใน Java protectedเป็น เรารู้ว่ามันคล้ายกับโมดิฟายเออร์เริ่มต้นโดยมีหนึ่งข้อยกเว้นซึ่งคลาสย่อยสามารถเห็นได้ แต่อย่างไร นี่คือตัวอย่างที่หวังว่าจะทำให้เกิดความสับสน:

  • สมมติว่าเรามี 2 คลาส; FatherและSonแต่ละชุดของมัน:

    package fatherpackage;
    
    public class Father
    {
    
    }
    
    -------------------------------------------
    
    package sonpackage;
    
    public class Son extends Father
    {
    
    }
  • ลองเพิ่มวิธีการป้องกันการfoo()Father

    package fatherpackage;
    
    public class Father
    {
        protected void foo(){}
    }
  • วิธีการนี้foo()สามารถเรียกได้ใน 4 บริบท:

    1. ภายในคลาสที่อยู่ในแพคเกจเดียวกันกับที่foo()กำหนดไว้ ( fatherpackage):

      package fatherpackage;
      
      public class SomeClass
      {
          public void someMethod(Father f, Son s)
          {
              f.foo();
              s.foo();
          }
      }
    2. ภายในคลาสย่อยบนอินสแตนซ์ปัจจุบันผ่านthisหรือsuper:

      package sonpackage;
      
      public class Son extends Father
      {
          public void sonMethod()
          {
              this.foo();
              super.foo();
          }
      }
    3. ในการอ้างอิงที่มีประเภทเป็นชั้นเดียวกัน:

      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();
          }
      }
    4. ในการอ้างอิงที่มีประเภทเป็นระดับผู้ปกครองและมันอยู่ในแพคเกจที่foo()มีการกำหนด ( fatherpackage) [นี้สามารถรวมอยู่ในบริบทหมายเลข 1]:

      package fatherpackage;
      
      public class Son extends Father
      {
          public void sonMethod(Father f)
          {
              f.foo();
          }
      }
  • สถานการณ์ต่อไปนี้ไม่ถูกต้อง

    1. ในการอ้างอิงที่มีประเภทเป็นระดับผู้ปกครองและมันอยู่นอกแพคเกจที่foo()มีการกำหนด ( fatherpackage):

      package sonpackage;
      
      public class Son extends Father
      {
          public void sonMethod(Father f)
          {
              f.foo(); // compilation error
          }
      }
    2. ไม่ใช่คลาสย่อยภายในแพ็กเกจของคลาสย่อย (คลาสย่อยสืบทอดสมาชิกที่ได้รับการปกป้องจากพาเรนต์และทำให้เป็นไพรเวตกับคลาสที่ไม่ใช่คลาสย่อย):

      package sonpackage;
      
      public class SomeClass
      {
          public void someMethod(Son s) throws Exception
          {
              s.foo(); // compilation error
          }
      }

Object#clone()เป็นตัวอย่างของprotectedสมาชิก
Eng.Fouad

ความแตกต่างระหว่างการทำsuper.foo()และสถานการณ์ที่ไม่ถูกต้องครั้งแรกf.foo()คืออะไร?
cst1992

1
@ cst1992 มันดูสับสน แต่ดู Java Language Specification 6.6.2: "สมาชิกที่ได้รับการป้องกันหรือตัวสร้างของวัตถุอาจถูกเข้าถึงได้จากนอกแพ็คเกจที่มีการประกาศโดยรหัสที่รับผิดชอบการใช้งานของวัตถุนั้น" ด้วย super.foo () การอ้างอิง "super" คือ "รับผิดชอบโดยตรงต่อการใช้งาน" แต่การอ้างอิง "f" ไม่ได้เป็น ทำไม? เพราะคุณสามารถมั่นใจได้ 100% ว่า "super" เป็นประเภทพ่อ แต่ไม่ใช่สำหรับ "f" เวลาทำงานอาจเป็นประเภทย่อยของพระบิดา ดูdocs.oracle.com/javase/specs/jls/se9/html/…
skomisa

1
protectedมันสดชื่นในการอ่านคำตอบจากคนที่เข้าใจ น่าเสียดายที่คำตอบอื่น ๆ ทั้งหมดในหน้านี้ที่กำหนดเอาผิดprotectedไปนิดหน่อย
Dawood ibn Kareem

30

เอกชน

  • วิธีการตัวแปรและตัวสร้าง

วิธีการตัวแปรและตัวสร้างที่มีการประกาศส่วนตัวสามารถเข้าถึงได้เฉพาะในชั้นเรียนที่ประกาศตัวเอง

  • คลาสและส่วนต่อประสาน

ตัวแก้ไขการเข้าถึงส่วนตัวเป็นระดับการเข้าถึงที่ จำกัด ที่สุด คลาสและอินเทอร์เฟซไม่สามารถเป็นส่วนตัวได้

บันทึก

ตัวแปรที่ประกาศส่วนตัวสามารถเข้าถึงได้นอกชั้นเรียนหากวิธีการทะเยอทะยานของประชาชนที่มีอยู่ในชั้นเรียน ตัวแปรเมธอดและตัวสร้างที่ถูกประกาศการป้องกันในซูเปอร์คลาสสามารถเข้าถึงได้โดยคลาสย่อยในแพ็คเกจอื่นหรือคลาสใด ๆ ภายในแพ็กเกจของคลาสสมาชิกที่ได้รับการป้องกัน


มีการป้องกัน

  • คลาสและส่วนต่อประสาน

ตัวดัดแปลงการเข้าถึงที่ได้รับการป้องกันไม่สามารถใช้กับคลาสและอินเทอร์เฟซได้

วิธีการสามารถประกาศเขตข้อมูลได้รับการป้องกันอย่างไรก็ตามวิธีการและเขตข้อมูลในอินเทอร์เฟซไม่สามารถประกาศได้รับการป้องกัน

บันทึก

การเข้าถึงที่ได้รับการป้องกันจะช่วยให้คลาสย่อยมีโอกาสที่จะใช้เมธอดหรือตัวแปรตัวช่วยในขณะที่ป้องกันไม่ให้คลาสที่ไม่เกี่ยวข้องพยายามใช้มัน


สาธารณะ

คลาสวิธีการตัวสร้างอินเทอร์เฟซ ฯลฯ ประกาศสาธารณะสามารถเข้าถึงได้จากคลาสอื่น ๆ

ดังนั้นฟิลด์วิธีการบล็อกที่ประกาศในคลาสสาธารณะสามารถเข้าถึงได้จากคลาสใด ๆ ที่เป็นของ Java Universe

  • แพ็คเกจต่าง ๆ

อย่างไรก็ตามหากคลาสสาธารณะที่เราพยายามเข้าถึงนั้นอยู่ในแพ็คเกจอื่นแล้วจะต้องมีการนำเข้าคลาสสาธารณะ

เนื่องจากการสืบทอดคลาสวิธีสาธารณะและตัวแปรทั้งหมดของคลาสจะได้รับการสืบทอดโดยคลาสย่อย


เริ่มต้น - ไม่มีคำหลัก:

ตัวดัดแปลงการเข้าถึงเริ่มต้นหมายความว่าเราไม่ได้ประกาศตัวดัดแปลงการเข้าถึงอย่างชัดเจนสำหรับคลาสฟิลด์วิธีการ ฯลฯ

  • ภายในแพ็คเกจเดียวกัน

ตัวแปรหรือเมธอดที่ประกาศโดยไม่มีตัวควบคุมการเข้าถึงใด ๆ สามารถใช้ได้กับคลาสอื่นในแพ็คเกจเดียวกัน ฟิลด์ในอินเทอร์เฟซเป็นแบบสแตติกสาธารณะสุดท้ายและวิธีการในอินเทอร์เฟซโดยสาธารณะเริ่มต้น

บันทึก

เราไม่สามารถแทนที่เขตข้อมูลแบบคงที่หากคุณพยายามแทนที่มันจะไม่แสดงข้อผิดพลาดใด ๆ แต่มันไม่ทำงานในสิ่งที่เรายกเว้น

คำตอบที่เกี่ยวข้อง

ลิงค์อ้างอิง

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


21

ความแตกต่างสามารถพบได้ในลิงก์ที่มีอยู่แล้ว แต่มักใช้อันใดอันหนึ่งลงมาใน "หลักการแห่งความรู้น้อยที่สุด" อนุญาตให้มองเห็นได้น้อยที่สุดที่จำเป็นเท่านั้น


20

ส่วนตัว : จำกัด การเข้าถึงชั้นเรียนเท่านั้น

ค่าเริ่มต้น (ไม่มีตัวแก้ไข) : การ จำกัด การเข้าถึงคลาสและแพ็คเกจ

ได้รับการป้องกัน : การเข้าถึงคลาสแพคเกจและคลาสย่อยที่ จำกัด (ทั้งภายในและภายนอกแพ็คเกจ)

สาธารณะ : เข้าถึงคลาสแพ็คเกจ (ทั้งหมด) และคลาสย่อย ... สั้น ๆ ทุกที่


17

ตัวดัดแปลงการเข้าถึงมีไว้เพื่อ จำกัด การเข้าถึงในหลายระดับ

สาธารณะ:โดยทั่วไปแล้วจะง่ายเหมือนที่คุณสามารถเข้าถึงได้จากทุกคลาสไม่ว่าจะอยู่ในแพ็คเกจเดียวกันหรือไม่ก็ตาม

ในการเข้าถึงหากคุณอยู่ในแพ็คเกจเดียวกันคุณสามารถเข้าถึงได้โดยตรง แต่ถ้าคุณอยู่ในแพ็คเกจอื่นคุณสามารถสร้างวัตถุของคลาสได้

เริ่มต้น:สามารถเข้าถึงได้ในแพ็คเกจเดียวกันจากคลาสใด ๆ ของแพ็คเกจ

ในการเข้าถึงคุณสามารถสร้างวัตถุของชั้นเรียน แต่คุณไม่สามารถเข้าถึงตัวแปรนี้นอกแพ็คเกจ

ได้รับการป้องกัน:คุณสามารถเข้าถึงตัวแปรในแพ็คเกจเดียวกันรวมถึงคลาสย่อยในแพ็คเกจอื่น ๆ ได้ ดังนั้นโดยทั่วไปมันเป็นพฤติกรรมเริ่มต้น + ที่สืบทอดมา

ในการเข้าถึงฟิลด์ที่ได้รับการป้องกันที่กำหนดไว้ในคลาสพื้นฐานคุณสามารถสร้างวัตถุของคลาสย่อย

ส่วนตัว: สามารถเข้าถึงได้ในระดับเดียวกัน

ในวิธีการที่ไม่คงที่คุณสามารถเข้าถึงได้โดยตรงเนื่องจากการอ้างอิงนี้ (เช่นในตัวสร้าง) แต่การเข้าถึงในวิธีการคงที่คุณต้องสร้างวัตถุของชั้นเรียน


16

เข้าถึงตัวดัดแปลงใน Java

ตัวดัดแปลงการเข้าถึง Java ถูกใช้เพื่อจัดเตรียมการควบคุมการเข้าถึงใน Java

1. ค่าเริ่มต้น:

เข้าถึงคลาสได้ในแพ็คเกจเดียวกันเท่านั้น

ตัวอย่างเช่น,

// Saved in file A.java
package pack;

class A{
  void msg(){System.out.println("Hello");}
}

// Saved in file B.java
package mypack;
import pack.*;

class B{
  public static void main(String args[]){
   A obj = new A(); // Compile Time Error
   obj.msg(); // Compile Time Error
  }
}

การเข้าถึงนี้ถูก จำกัด มากกว่าสาธารณะและได้รับการคุ้มครอง แต่ จำกัด น้อยกว่าส่วนตัว

2. สาธารณะ

สามารถเข้าถึงได้จากทุกที่ (การเข้าถึงทั่วโลก)

ตัวอย่างเช่น,

// Saved in file A.java

package pack;
public class A{
  public void msg(){System.out.println("Hello");}
}

// Saved in file B.java

package mypack;
import pack.*;

class B{
  public static void main(String args[]){
    A obj = new A();
    obj.msg();
  }
}

เอาท์พุท: สวัสดีครับ

3. ส่วนตัว

สามารถเข้าถึงได้เฉพาะภายในชั้นเรียนเดียวกัน

หากคุณพยายามที่จะเข้าถึงสมาชิกส่วนตัวในชั้นหนึ่งในอีกคนหนึ่งจะโยนข้อผิดพลาดรวบรวม ตัวอย่างเช่น,

class A{
  private int data = 40;
  private void msg(){System.out.println("Hello java");}
}

public class Simple{
  public static void main(String args[]){
    A obj = new A();
    System.out.println(obj.data); // Compile Time Error
    obj.msg(); // Compile Time Error
  }
}

4. ป้องกัน

เข้าถึงได้เฉพาะคลาสที่อยู่ในแพ็คเกจเดียวกันและไปที่คลาสย่อย

ตัวอย่างเช่น,

// Saved in file A.java
package pack;
public class A{
  protected void msg(){System.out.println("Hello");}
}

// Saved in file B.java
package mypack;
import pack.*;

class B extends A{
  public static void main(String args[]){
    B obj = new B();
    obj.msg();
  }
}

เอาท์พุต: สวัสดี

ป้อนคำอธิบายภาพที่นี่


14
  • สาธารณะ - เข้าถึงได้จากทุกที่ในแอปพลิเคชัน

  • เริ่มต้น - สามารถเข้าถึงได้จากแพคเกจ

  • การป้องกัน - เข้าถึงได้จากแพ็คเกจและคลาสย่อยในแพ็คเกจอื่น เช่นกัน

  • ส่วนตัว - เข้าถึงได้จากชั้นเรียนเท่านั้น


14

มองเห็นแพคเกจ ค่าเริ่มต้น ไม่จำเป็นต้องมีตัวดัดแปลง

ปรากฏแก่ชั้นเรียนเท่านั้น ( ส่วนตัว )

ปรากฏแก่โลก ( สาธารณะ )

ปรากฏแก่แพ็คเกจและคลาสย่อยทั้งหมด ( ได้รับการป้องกัน )

ตัวแปรและวิธีการสามารถประกาศได้โดยไม่ต้องมีการดัดแปลงใด ๆ ที่เรียกว่า ตัวอย่างเริ่มต้น:

String name = "john";

public int age(){
    return age;
}

ตัวแก้ไขการเข้าถึงส่วนตัว - ส่วนตัว:

เมธอดตัวแปรและตัวสร้างที่ถูกประกาศเป็นส่วนตัวสามารถเข้าถึงได้ภายในคลาสที่ประกาศเท่านั้น ตัวแก้ไขการเข้าถึงส่วนตัวเป็นระดับการเข้าถึงที่ จำกัด ที่สุด คลาสและอินเทอร์เฟซไม่สามารถเป็นส่วนตัวได้

ตัวแปรที่ประกาศส่วนตัวสามารถเข้าถึงได้นอกชั้นเรียนหากมีวิธีการทะเยอทะยานสาธารณะที่มีอยู่ในชั้นเรียน

การใช้ตัวดัดแปลงส่วนตัวเป็นวิธีหลักที่วัตถุห่อหุ้มตัวเองและซ่อนข้อมูลจากโลกภายนอก

ตัวอย่าง:

Public class Details{

    private String name;

    public void setName(String n){
        this.name = n;
    }

    public String getName(){
        return this.name;
    }
}

ตัวดัดแปลงการเข้าถึงสาธารณะ - สาธารณะ:

คลาสวิธีการตัวสร้างส่วนต่อประสานและอื่น ๆ ที่ประกาศสู่สาธารณะสามารถเข้าถึงได้จากคลาสอื่น ๆ ดังนั้นฟิลด์เมธอดบล็อกที่ประกาศภายในคลาสพับลิกสามารถเข้าถึงได้จากคลาสใด ๆ ที่เป็นของจักรวาล Java

อย่างไรก็ตามหากคลาสสาธารณะที่เราพยายามเข้าถึงนั้นอยู่ในแพ็คเกจอื่นแล้วจะต้องมีการนำเข้าคลาสสาธารณะ

เนื่องจากการสืบทอดคลาสวิธีสาธารณะและตัวแปรทั้งหมดของคลาสจะได้รับการสืบทอดโดยคลาสย่อย

ตัวอย่าง:

public void cal(){

}

ตัวดัดแปลงการเข้าถึงที่ได้รับการป้องกัน - ได้รับการป้องกัน:

ตัวแปรเมธอดและตัวสร้างที่ถูกประกาศการป้องกันในซูเปอร์คลาสสามารถเข้าถึงได้โดยคลาสย่อยในแพ็คเกจอื่นหรือคลาสใด ๆ ภายในแพ็กเกจของคลาสสมาชิกที่ได้รับการป้องกัน

ตัวดัดแปลงการเข้าถึงที่ได้รับการป้องกันไม่สามารถใช้กับคลาสและอินเทอร์เฟซได้ วิธีการสามารถประกาศเขตข้อมูลได้รับการป้องกันอย่างไรก็ตามวิธีการและเขตข้อมูลในอินเทอร์เฟซไม่สามารถประกาศได้รับการป้องกัน

การเข้าถึงที่ได้รับการป้องกันจะช่วยให้คลาสย่อยมีโอกาสที่จะใช้เมธอดหรือตัวแปรตัวช่วยในขณะที่ป้องกันไม่ให้คลาสที่ไม่เกี่ยวข้องพยายามใช้มัน

class Van{

    protected boolean speed(){

    }
}

class Car{
    boolean speed(){
    }

}

12

หน้านี้เขียนได้ดีเกี่ยวกับตัวดัดแปลงการเข้าถึง & ป้องกันที่เป็นค่าเริ่มต้น

ได้รับการป้องกัน: ตัวดัดแปลงการเข้าถึงที่ได้รับการป้องกันนั้นมีความยุ่งยากเล็กน้อยและคุณสามารถพูดได้ว่าเป็นตัวเสริมของตัวดัดแปลงการเข้าถึงเริ่มต้น สมาชิกที่ได้รับความคุ้มครองจะเหมือนกับสมาชิกเริ่มต้นจนถึงการเข้าถึงในแพ็คเกจเดียวกัน ความแตกต่างก็คือสมาชิกที่ได้รับความคุ้มครองจะสามารถเข้าถึงคลาสย่อยของคลาสที่สมาชิกถูกประกาศซึ่งอยู่นอกแพ็คเกจที่มีคลาสพาเรนต์

แต่สมาชิกที่ได้รับการปกป้องเหล่านี้จะ“ เข้าถึงได้จากภายนอกแพ็คเกจเท่านั้นโดยการรับมรดก” เช่นคุณสามารถเข้าถึงสมาชิกที่ได้รับการป้องกันของคลาสในคลาสย่อยที่มีอยู่ในแพ็คเกจอื่น ๆ ได้โดยตรงราวกับว่าสมาชิกนั้นมีอยู่ในคลาสย่อยนั้นเอง แต่สมาชิกที่ได้รับการป้องกันนั้นจะไม่สามารถเข้าถึงได้ในคลาสย่อยนอกแพ็คเกจโดยใช้การอ้างอิงของคลาสพาเรนต์ ....


เพียงแค่เพิ่มนี้ "เมื่อเด็กเข้าถึงสมาชิกที่ได้รับการป้องกันของคลาสผู้ปกครองมันจะกลายเป็นส่วนตัว (หรือมากกว่านั้นฉันจะบอกว่าสมาชิกส่วนตัวพิเศษซึ่งสามารถสืบทอดโดยคลาสย่อยของคลาสย่อย) สมาชิกของคลาสย่อย"
อานันท์

9

คำตอบของเดวิดให้ความหมายของตัวดัดแปลงการเข้าถึงแต่ละตัว สำหรับการใช้แต่ละครั้งฉันขอแนะนำให้เผยแพร่คลาสทั้งหมดและวิธีการของแต่ละคลาสที่มีไว้สำหรับใช้ภายนอก (API) และทุกอย่างเป็นส่วนตัว

เมื่อเวลาผ่านไปคุณจะพัฒนาความรู้สึกเมื่อถึงเวลาที่จะทำให้บางคลาสแพคเกจส่วนตัวและเมื่อใดที่จะประกาศวิธีการบางอย่างที่ป้องกันเพื่อใช้ในคลาสย่อย


6

หมายเหตุ: นี่เป็นเพียงส่วนเสริมสำหรับคำตอบที่ได้รับการยอมรับ

นี้จะเกี่ยวข้องกับ Java เข้าถึงปรับเปลี่ยน

จากตัวดัดแปลงการเข้าถึง Java :

ตัวดัดแปลงการเข้าถึง Java ระบุคลาสที่สามารถเข้าถึงคลาสที่กำหนดและฟิลด์คอนสตรัคเตอร์และวิธีการ ตัวดัดแปลงการเข้าถึงสามารถระบุแยกต่างหากสำหรับคลาสตัวสร้างฟิลด์และเมธอด ตัวดัดแปลงการเข้าถึง Java บางครั้งก็ถูกอ้างถึงเป็นภาษาพูดเป็นตัวระบุการเข้าถึง Java แต่ชื่อที่ถูกต้องคือตัวดัดแปลงการเข้าถึง Java คลาส, ฟิลด์, ตัวสร้างและเมธอดสามารถมีหนึ่งในสี่ของตัวดัดแปลงการเข้าถึง Java ที่แตกต่างกัน:

  • รายการสินค้า
  • เอกชน
  • ค่าเริ่มต้น (แพคเกจ)
  • มีการป้องกัน
  • สาธารณะ

จากการควบคุมการเข้าถึงสมาชิกของบทเรียนแบบฝึกหัด:

ตัวดัดแปลงระดับการเข้าถึงจะกำหนดว่าคลาสอื่นสามารถใช้ฟิลด์ใดฟิลด์หนึ่งหรือเรียกใช้เมธอดเฉพาะ การควบคุมการเข้าถึงมีสองระดับ:

  • ที่ระดับบนสุด - สาธารณะหรือแพคเกจส่วนตัว (ไม่มีตัวแก้ไขที่ชัดเจน)
  • ในระดับสมาชิก - สาธารณะส่วนตัวป้องกันหรือแพคเกจส่วนตัว (ไม่มีตัวแก้ไขที่ชัดเจน)

คลาสอาจถูกประกาศด้วยโมดิฟายเออร์สาธารณะซึ่งในกรณีนี้คลาสนั้นจะปรากฏแก่ทุกคลาสทุกที่ หากคลาสไม่มีตัวแก้ไข (ค่าเริ่มต้นหรือที่รู้จักกันในชื่อแพคเกจส่วนตัว) จะสามารถมองเห็นได้ภายในแพ็คเกจของตัวเองเท่านั้น

ตารางต่อไปนี้แสดงการเข้าถึงสมาชิกที่ได้รับอนุญาตจากตัวดัดแปลงแต่ละตัว

╔═════════════╦═══════╦═════════╦══════════╦═══════╗
 Modifier     Class  Package  Subclass  World 
╠═════════════╬═══════╬═════════╬══════════╬═══════╣
 public       Y      Y        Y         Y     
 protected    Y      Y        Y         N     
 no modifier  Y      Y        N         N     
 private      Y      N        N         N     
╚═════════════╩═══════╩═════════╩══════════╩═══════╝

คอลัมน์ข้อมูลแรกระบุว่าคลาสนั้นมีการเข้าถึงสมาชิกที่กำหนดโดยระดับการเข้าถึง อย่างที่คุณเห็นชั้นเรียนมีสิทธิ์เข้าถึงสมาชิกของตัวเองเสมอ คอลัมน์ที่สองระบุว่าคลาสในแพ็กเกจเดียวกันกับคลาส (ไม่ว่าจะเป็นพาเรนต์) มีการเข้าถึงสมาชิกหรือไม่ คอลัมน์ที่สามระบุว่าคลาสย่อยของคลาสที่ประกาศภายนอกแพ็คเกจนี้มีสิทธิ์เข้าถึงสมาชิกหรือไม่ คอลัมน์ที่สี่ระบุว่าคลาสทั้งหมดมีการเข้าถึงสมาชิกหรือไม่

ระดับการเข้าถึงมีผลกับคุณในสองวิธี ขั้นแรกเมื่อคุณใช้คลาสที่มาจากแหล่งอื่นเช่นคลาสในแพลตฟอร์ม Java ระดับการเข้าถึงจะกำหนดสมาชิกของคลาสเหล่านั้นที่คลาสของคุณเองสามารถใช้ได้ ประการที่สองเมื่อคุณเขียนคลาสคุณต้องตัดสินใจว่าระดับการเข้าถึงใดที่ตัวแปรสมาชิกทุกตัวและทุกวิธีในชั้นเรียนของคุณควรมี


1
ส่วนเสริมคืออะไรและเหตุใดจึงไม่แก้ไขโพสต์ที่มีอยู่
sehe

ภาคผนวกคือตัวดัดแปลงการเข้าถึง ทำไมไม่แก้ไข? เพื่อรักษาคำตอบที่ยอมรับไม่เปลี่ยนแปลงเพื่อประโยชน์ในอดีตและเพื่อให้คำตอบของฉัน
ישואוהבאותך

5

ค่าเริ่มต้นที่ได้รับการป้องกันสาธารณะและส่วนตัวเป็นตัวดัดแปลงการเข้าถึง

พวกเขามีไว้สำหรับห่อหุ้มหรือซ่อนและแสดงเนื้อหาของชั้นเรียน

  1. ชั้นสามารถเป็นสาธารณะหรือเริ่มต้น
  2. สมาชิกของคลาสสามารถเป็นสาธารณะป้องกันค่าเริ่มต้นหรือส่วนตัว

ส่วนตัวไม่สามารถเข้าถึงได้นอกคลาสค่าเริ่มต้นสามารถเข้าถึงได้เฉพาะในแพ็คเกจ ได้รับการปกป้องในแพ็คเกจรวมถึงคลาสที่ขยายออกไป สาธารณะเปิดให้บริการสำหรับทุกคน

โดยปกติแล้วตัวแปรสมาชิกจะถูกกำหนดเป็นส่วนตัว แต่วิธีสมาชิกนั้นเป็นแบบสาธารณะ


Defaultไม่ได้เป็นตัวดัดแปลงการเข้าถึงและอีกสองตัวเป็น misspelt
user207421

5

บ่อยครั้งที่ฉันรู้ว่าการจดจำแนวคิดพื้นฐานของภาษาใด ๆ สามารถทำได้โดยการสร้างการเปรียบเทียบในโลกแห่งความเป็นจริง นี่คือการเปรียบเทียบของฉันสำหรับการทำความเข้าใจตัวดัดแปลงการเข้าถึงใน Java:

สมมติว่าคุณเป็นนักเรียนในมหาวิทยาลัยและคุณมีเพื่อนที่จะมาเยี่ยมคุณในช่วงสุดสัปดาห์ สมมติว่ามีรูปปั้นขนาดใหญ่ของผู้ก่อตั้งมหาวิทยาลัยอยู่ตรงกลางของมหาวิทยาลัย

  • เมื่อคุณพาเขาไปที่มหาวิทยาลัยสิ่งแรกที่คุณและเพื่อนของคุณเห็นคือรูปปั้นนี้ ซึ่งหมายความว่าทุกคนที่เดินในมหาวิทยาลัยสามารถดูรูปปั้นโดยไม่ได้รับอนุญาตจากมหาวิทยาลัย นี้จะทำให้รูปปั้นเป็นมหาชน

  • ถัดไปคุณต้องการพาเพื่อนไปที่หอพัก แต่เพื่อที่คุณจะต้องลงทะเบียนเขาในฐานะแขก ซึ่งหมายความว่าเขาได้รับทางเข้า (ซึ่งเหมือนกับของคุณ) เพื่อเข้าไปในอาคารต่าง ๆ ในมหาวิทยาลัย นี้จะทำให้การ์ดของเขาในฐานะคุ้มครอง

  • เพื่อนของคุณต้องการลงชื่อเข้าใช้ WiFi ของมหาวิทยาลัย แต่ไม่มีข้อมูลรับรองใด ๆ วิธีเดียวที่เขาจะออนไลน์ได้คือถ้าคุณแชร์การเข้าสู่ระบบกับเขา (โปรดจำไว้ว่านักเรียนทุกคนที่ไปมหาวิทยาลัยก็มีข้อมูลการเข้าสู่ระบบเหล่านี้ด้วย) นี้จะทำให้สิทธิเข้าสู่ระบบของคุณเป็นNO MODIFIER

  • ในที่สุดเพื่อนของคุณต้องการอ่านรายงานความคืบหน้าของคุณสำหรับภาคการศึกษาที่โพสต์บนเว็บไซต์ อย่างไรก็ตามนักเรียนทุกคนมีการเข้าสู่ระบบส่วนตัวของตนเองเพื่อเข้าถึงส่วนนี้ของเว็บไซต์วิทยาเขต นี้จะทำให้ข้อมูลประจำตัวของเหล่านี้เป็นส่วนตัว

หวังว่านี่จะช่วยได้!


4

เมื่อคุณนึกถึงตัวดัดแปลงการเข้าถึงให้ลองนึกถึงวิธีนี้ (ใช้กับทั้งตัวแปรและวิธีการ ):

public-> เข้าถึงได้จากทุกที่
private-> เข้าถึงได้เฉพาะภายในคลาสเดียวกันที่มีการประกาศ

ตอนนี้ความสับสนเกิดขึ้นเมื่อมันมาถึงdefaultและprotected

default-> ไม่มีคำหลักของตัวแก้ไขการเข้าถึง ซึ่งหมายความว่ามีให้อย่างเคร่งครัดภายในแพ็คเกจของคลาส ไม่มีแพคเกจภายนอกที่สามารถเข้าถึงได้

protected-> เข้มงวดน้อยกว่าเล็กน้อยdefaultและนอกเหนือจากคลาสแพ็กเกจเดียวกันที่สามารถเข้าถึงได้โดยคลาสย่อยภายนอกแพ็กเกจที่ถูกประกาศ


4

การเข้าถึง Java แก้ไขซึ่งคุณสามารถใช้

ป้อนคำอธิบายรูปภาพที่นี่

ปรับปรุงการเข้าถึงสามารถใช้สำหรับclass, [เกี่ยวกับ] , ลองเข้าถึงคลาสย่อยหรือลบล้างสิ่งนี้fieldmethod

  • การเข้าถึงfieldหรือmethodผ่าน aclassจะผ่าน
  • มรดก classตัวดัดแปลงการเข้าถึงSuccessor (คลาสย่อย) สามารถเป็นอะไรก็ได้ methodตัวดัดแปลงการเข้าถึงตัวทำต่อ(แทนที่) ควรเหมือนกันหรือขยาย

ระดับระดับบนสุด (ขอบเขตระดับแรก) สามารถและpublic [เกี่ยวกับ]สามารถมีหนึ่งในนั้นได้defaultNested class

package ใช้ไม่ได้กับลำดับชั้นแพ็คเกจ

ตัวดัดแปลงการเข้าถึงที่รวดเร็ว


2

มันคือทั้งหมดที่เกี่ยวกับการห่อหุ้ม (หรือตามที่โจฟิลลิปส์ระบุความรู้น้อยที่สุด )

เริ่มต้นด้วยข้อ จำกัด มากที่สุด (ส่วนตัว) และดูว่าคุณต้องการตัวดัดแปลงที่ จำกัด น้อยกว่าหรือไม่

เราทุกคนใช้วิธีและตัวดัดแปลงสมาชิกเช่นส่วนตัวสาธารณะ ... แต่สิ่งหนึ่งที่นักพัฒนาน้อยเกินไปที่ทำคือใช้แพ็คเกจเพื่อจัดระเบียบโค้ดอย่างมีเหตุผล

ตัวอย่างเช่น: คุณอาจใส่วิธีการรักษาความปลอดภัยที่สำคัญในแพ็คเกจ 'ความปลอดภัย' แล้วใส่คลาสที่สาธารณะซึ่งเข้าถึงบางส่วนของรหัสรักษาความปลอดภัยที่เกี่ยวข้องในแพคเกจนี้ แต่ให้การเรียนการรักษาความปลอดภัยอื่น ๆแพคเกจส่วนตัว ดังนั้นผู้พัฒนารายอื่นจะสามารถใช้คลาสที่เปิดเผยต่อสาธารณะจากภายนอกแพ็คเกจนี้เท่านั้น (เว้นแต่พวกเขาจะเปลี่ยนโมดิฟายเออร์) นี่ไม่ใช่คุณสมบัติความปลอดภัย แต่จะแนะนำการใช้งาน

Outside world -> Package (SecurityEntryClass ---> Package private classes)

อีกสิ่งหนึ่งคือคลาสที่ต้องพึ่งพากันมากอาจจบลงด้วยแพ็คเกจเดียวกันและในที่สุดก็สามารถถูกปรับโครงสร้างใหม่หรือรวมเข้าด้วยกันหากการพึ่งพานั้นแข็งแกร่งเกินไป

หากคุณตั้งค่าทุกอย่างเป็นสาธารณะจะไม่ชัดเจนว่าควรหรือไม่ควรเข้าถึงซึ่งอาจนำไปสู่การเขียน javadoc จำนวนมาก (ซึ่งไม่บังคับใช้สิ่งใดผ่านคอมไพเลอร์ ... )


2

ส่วนตัวที่มีการป้องกันแบบสาธารณะที่สมบูรณ์แบบสำหรับการเปรียบเทียบที่ตัวแปรข้อมูลประเภท

ต่อไปนี้แผนภาพบล็อกอธิบายวิธีการข้อมูลสมาชิกของชั้นฐานจะได้รับมรดกเมื่อมาระดับโหมดการเข้าถึงเป็นส่วนตัว

ป้อนคำอธิบายรูปภาพที่นี่

หมายเหตุ: การประกาศข้อมูลสมาชิกด้วยตัวระบุการเข้าถึงส่วนตัวเรียกว่าการซ่อนข้อมูล

ที่มา: ตัวระบุการเข้าถึง - ส่วนตัวสาธารณะและได้รับการป้องกัน


1
คำถามเกี่ยวกับ Java ไม่ใช่ C ++
เบอนัวต์

1
@Benoit แต่สิ่งที่ฉันโพสต์รูปภาพในแบบพิเศษนั้นไม่เหมือนกันสำหรับทั้ง: java และ c ++? กฎนี้ใช้ไม่ได้กับจาวาด้วย? ขอบคุณ
leonidaa

2
ใน C ++ มีเพียง 3 ตัวดัดแปลงในขณะที่มี 4 ใน java
เบอนัวต์

1
การเปรียบเทียบนั้นดี แต่ตัวระบุการเข้าถึงเริ่มต้นหายไป
mss

1
OP ถามคำถาม "ความแตกต่างระหว่างสาธารณะการป้องกันแพคเกจส่วนตัวและส่วนตัวใน Java คืออะไร"
JL_SO

2

สองเซ็นต์ของฉัน :)

เอกชน:

class ->คลาสระดับบนสุดไม่สามารถเป็นส่วนตัวได้ คลาสภายในสามารถเป็นส่วนตัวซึ่งสามารถเข้าถึงได้จากคลาสเดียวกัน

อินสแตนซ์ตัวแปร ->เข้าถึงได้เฉพาะในชั้นเรียน ไม่สามารถเข้าถึงนอกชั้นเรียน

แพคเกจและเอกชน:

class ->คลาสระดับบนสุดสามารถเป็นแพคเกจส่วนตัว สามารถเข้าถึงได้จากแพ็คเกจเดียวกันเท่านั้น ไม่ใช่จากแพ็คเกจย่อยไม่ใช่จากแพ็คเกจภายนอก

ตัวแปรอินสแตนซ์ ->เข้าถึงได้จากแพ็คเกจเดียวกัน ไม่ใช่จากแพ็คเกจย่อยไม่ใช่จากแพ็คเกจภายนอก

มีการป้องกัน:

class ->คลาสระดับบนสุดไม่สามารถป้องกันได้

ตัวแปรอินสแตนซ์ ->เข้าถึงได้เฉพาะในแพ็คเกจหรือแพ็กเกจย่อยเดียวกัน สามารถเข้าถึงได้เฉพาะนอกแพ็คเกจเท่านั้นขณะขยายชั้นเรียน

ส่วนกลาง:

class ->เข้าถึงได้จากแพ็คเกจ / แพ็คเกจย่อย / แพ็คเกจอื่น

ตัวแปรอินสแตนซ์ ->เข้าถึงได้จากแพ็คเกจ / แพ็คเกจย่อย / แพ็คเกจอื่น

นี่คือคำตอบโดยละเอียด

https://github.com/junto06/java-4-beginners/blob/master/basics/access-modifier.md


1
  • สาธารณะ

    หากสมาชิกชั้นเรียนมีการประกาศต่อสาธารณะก็สามารถเข้าถึงได้จากทุกที่

  • มีการป้องกัน

    หากสมาชิกคลาสได้รับการประกาศพร้อมการป้องกันคีย์เวิร์ดคุณสามารถเข้าถึงได้จากสมาชิกคลาสเดียวกันสมาชิกคลาสภายนอกภายในแพ็กเกจเดียวกันและสมาชิกคลาสที่สืบทอด หากสมาชิกคลาสได้รับการปกป้องจะไม่สามารถเข้าถึงได้จากคลาสแพ็กเกจภายนอกยกเว้นคลาสแพ็กเกจภายนอกนั้นสืบทอดมาเช่นขยายแพ็กเกจซูเปอร์คลาสอื่น แต่สมาชิกคลาสที่ได้รับการปกป้องจะมีให้ในคลาสแพ็กเกจเดียวกันเสมอไม่ว่าสภาพอากาศของคลาสแพ็กเกจเดียวกันจะสืบทอดหรือไม่ก็ตาม

  • ค่าเริ่มต้น

    ในค่าเริ่มต้นของ Java ไม่ได้เป็นคำหลักที่ปรับปรุงการเข้าถึง หากสมาชิกคลาสถูกประกาศโดยไม่มีคีย์เวิร์ดตัวดัดแปลงการเข้าถึงใด ๆ ดังนั้นในกรณีนี้ถือว่าเป็นสมาชิกดีฟอลต์ สมาชิกคลาสเริ่มต้นพร้อมใช้งานสำหรับสมาชิกคลาสแพ็คเกจเดียวกันเสมอ แต่สมาชิกคลาสภายนอกแพ็กเกจไม่สามารถเข้าถึงสมาชิกคลาสเริ่มต้นได้แม้ว่าคลาสภายนอกจะเป็นคลาสย่อยซึ่งแตกต่างจากสมาชิกที่ได้รับความคุ้มครอง

  • เอกชน

    หากสมาชิกคลาสได้รับการประกาศพร้อมการป้องกันคีย์เวิร์ดในกรณีนี้สมาชิกคลาสเดียวกันเท่านั้นที่สามารถใช้ได้


-1

Access Specifiers ใน Java: มีตัวระบุการเข้าถึง 4 ตัวใน java คือส่วนตัวแพคเกจส่วนตัว (ค่าเริ่มต้น) การป้องกันและสาธารณะในการเพิ่มลำดับการเข้าถึง

ส่วนตัว : เมื่อคุณกำลังพัฒนาบางคลาสและคุณต้องการให้สมาชิกของคลาสนี้ไม่ถูกเปิดเผยนอกคลาสนี้คุณควรประกาศว่าเป็นคลาสส่วนตัว สมาชิกส่วนตัวสามารถเข้าถึงได้เฉพาะในชั้นเรียนที่พวกเขาถูกกำหนดเช่นชั้นล้อมรอบ สมาชิกส่วนตัวสามารถเข้าถึงได้ในการอ้างอิง 'นี้' และในอินสแตนซ์อื่นของคลาสที่ล้อมรอบสมาชิกเหล่านี้ แต่ภายในนิยามของคลาสนี้เท่านั้น

แพ็คเกจ - ส่วนตัว (ค่าเริ่มต้น) : ตัวระบุการเข้าถึงนี้จะให้การเข้าถึงที่ระบุโดยตัวระบุการเข้าถึงส่วนตัวนอกเหนือจากการเข้าถึงที่อธิบายไว้ด้านล่าง

เมื่อคุณกำลังพัฒนาแพคเกจบางอย่างและด้วยเหตุนี้บางคลาส (พูด Class1) ภายในนั้นคุณอาจใช้ตัวระบุการเข้าถึงเริ่มต้น (ไม่จำเป็นต้องกล่าวถึงอย่างชัดแจ้ง) เพื่อเปิดเผยสมาชิกภายในคลาสไปยังคลาสอื่นภายในแพ็กเกจ (เดียวกัน) ของคุณ ในคลาสอื่น ๆ เหล่านี้ (ภายในแพ็คเกจเดียวกัน) คุณสามารถเข้าถึงสมาชิกเริ่มต้นเหล่านี้ในอินสแตนซ์ของ Class1 นอกจากนี้คุณสามารถเข้าถึงสมาชิกเริ่มต้นเหล่านี้ภายในคลาสย่อยของ Class1, พูด Class2 (ในการอ้างอิงนี้หรือบนอินสแตนซ์ของ Class1 หรือบนอินสแตนซ์ของ Class2)

โดยทั่วไปภายในแพ็คเกจเดียวกันคุณสามารถเข้าถึงสมาชิกเริ่มต้นในอินสแตนซ์ของคลาสโดยตรงหรืออ้างอิง 'นี้' ในคลาสย่อย

ได้รับการป้องกัน : ตัวระบุการเข้าถึงนี้จะให้การเข้าถึงที่ระบุโดยตัวระบุการเข้าถึงส่วนตัวรวมถึงการเข้าถึงที่อธิบายไว้ด้านล่าง

เมื่อคุณกำลังพัฒนาแพ็กเกจและด้วยเหตุนี้บางคลาส (พูด Class1) ภายในนั้นคุณควรใช้ตัวระบุการเข้าถึงที่ได้รับการป้องกันสำหรับข้อมูลสมาชิกภายใน Class1 หากคุณไม่ต้องการให้สมาชิกนี้เข้าถึงได้นอกแพ็คเกจของคุณ (พูดในแพ็คเกจของผู้บริโภค แพ็คเกจของคุณคือไคลเอนต์ที่ใช้ API ของคุณ) โดยทั่วไป แต่คุณต้องการยกเว้นและอนุญาตให้เข้าถึงสมาชิกนี้เฉพาะเมื่อไคลเอนต์เขียนคลาสพูด Class2 ที่ขยาย Class1 ดังนั้นโดยทั่วไปสมาชิกที่ได้รับความคุ้มครองจะสามารถเข้าถึงได้โดยการอ้างอิง 'this' ในคลาสที่ได้รับเช่น Class2 และบนอินสแตนซ์ที่ชัดเจนของ Class2

โปรดทราบ:

  1. คุณจะไม่สามารถเข้าถึงสมาชิกที่ได้รับการป้องกันที่ได้รับการสืบทอดของ Class1 ใน Class2 ได้หากคุณพยายามเข้าถึงสมาชิกในอินสแตนซ์ที่ชัดเจนของ Class1 แม้ว่าจะได้รับการสืบทอดมาแล้วก็ตาม
  2. เมื่อคุณเขียน Class3 คลาสอื่นภายในแพ็คเกจเดียวกัน / แตกต่างที่ขยาย Class2 สมาชิกที่ได้รับความคุ้มครองจาก Class1 จะสามารถเข้าถึงได้ในการอ้างอิงนี้และบนอินสแตนซ์ที่ชัดเจนของ Class3 สิ่งนี้จะเป็นจริงสำหรับลำดับชั้นใด ๆ ที่ถูกขยายนั่นคือสมาชิกที่ได้รับความคุ้มครองจะยังคงสามารถเข้าถึงได้ในการอ้างอิงนี้หรืออินสแตนซ์ของคลาสที่ขยายเพิ่มเติม โปรดทราบว่าใน Class3 หากคุณสร้างอินสแตนซ์ของ Class2 คุณจะไม่สามารถเข้าถึงสมาชิกที่ได้รับการป้องกันจาก Class1 แม้ว่าจะได้รับการสืบทอด

ดังนั้นบรรทัดล่างคือสมาชิกที่ได้รับความคุ้มครองสามารถเข้าถึงได้ในแพ็คเกจอื่น ๆ เฉพาะในกรณีที่คลาสจากแพ็คเกจอื่นนี้ขยายคลาสที่ล้อมรอบสมาชิกที่ได้รับการป้องกันนี้และสมาชิกที่ได้รับความคุ้มครองสามารถเข้าถึงได้ในการอ้างอิง ชั้น

สาธารณะ : ตัวระบุการเข้าถึงนี้จะให้การเข้าถึงที่ระบุโดยตัวระบุการเข้าถึงที่ได้รับการป้องกันนอกเหนือจากการเข้าถึงที่อธิบายไว้ด้านล่าง

เมื่อคุณกำลังพัฒนาแพ็กเกจและด้วยเหตุนี้บางคลาส (พูด Class1) ภายในนั้นคุณควรใช้ตัวระบุการเข้าถึงสาธารณะสำหรับข้อมูลสมาชิกภายใน Class1 ถ้าคุณต้องการให้สมาชิกนี้สามารถเข้าถึงได้ในแพ็คเกจอื่น ๆ ในอินสแตนซ์ของ Class1 ที่สร้างในคลาสอื่น ๆ บรรจุภัณฑ์ โดยพื้นฐานตัวระบุการเข้าถึงนี้ควรใช้เมื่อคุณต้องการเปิดเผยข้อมูลสมาชิกของคุณสู่โลกโดยไม่มีเงื่อนไขใด ๆ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.