เหตุใดจึงไม่มีตัวแก้ไขการเข้าถึง 'คลาสย่อยเท่านั้น' ใน Java


17

ใน Java มีตัวดัดแปลงการเข้าถึงที่ใช้ได้สี่วิธีสำหรับวิธีการ:

public - คลาสใด ๆ สามารถใช้วิธีนี้

protected - คลาสในแพ็คเกจเดียวกันและคลาสย่อยในแพ็คเกจใด ๆ สามารถใช้วิธีนี้ได้

private - คลาสนี้เท่านั้นที่สามารถใช้วิธีนี้

no modifier ("แพ็คเกจส่วนตัว") - เฉพาะคลาสในแพ็คเกจเดียวกันเท่านั้นที่สามารถใช้วิธีนี้ได้

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

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

มีเหตุผลที่ไม่มีsubclasses-onlyตัวดัดแปลงการเข้าถึงใน Java หรือไม่? ดูเหมือนแปลกมากสำหรับฉัน ฉันพลาดอะไรไปรึเปล่า?

นอกจากนี้subclasses-onlyตัวดัดแปลงการเข้าถึงจะมีประโยชน์เมื่อคุณต้องการเปิดเผยตัวแปรเฉพาะคลาสย่อย ซึ่งสำหรับฉันเกิดขึ้นมาก

คำตอบ:


10

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

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


15
"และบังคับใช้เฉพาะคลาสพาเรนต์และคลาสย่อยที่อยู่ในแพ็คเกจเดียวกัน" - ตอนนี้เราจะทำเช่นนั้นได้อย่างไร!
JimmyB

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

13

Java เดิมมีตัวดัดแปลงดังกล่าว มันถูกเขียนprivate protectedแต่ลบออกใน Java 1.0

ฉันคิดว่านั่นเป็นการเรียกการตัดสินว่าความซับซ้อนพิเศษนั้นไม่คุ้มกับค่าใช้จ่าย

คุณลักษณะภาษาทุกภาษามีค่าใช้จ่าย: ในการสอนให้กับโปรแกรมเมอร์ใหม่ ในเอกสาร; ในการนำไปใช้ในคอมไพเลอร์, JVM, และเครื่องมือ dev ในการให้เหตุผลเกี่ยวกับความถูกต้องของโปรแกรม ในการบังคับวิวัฒนาการทางภาษาในอนาคต และอื่น ๆ. คุณสมบัติภาษามีปฏิสัมพันธ์ซึ่งกันและกันอาจเกิดจากการโต้ตอบN 2

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

ประโยชน์ของprivate protectedฟีเจอร์นั้นเล็กเนื่องจากแพ็คเกจเป็นหน่วยหลักของโมดุล


1
ดังนั้นจึงมีรุ่น Java ก่อน 1.0?
Mark Yisri

1
@MarkYisri Java มีการเผยแพร่อัลฟ่าและเบต้าสาธารณะในปี 1995 และมีการเขียนโค้ดที่ค่อนข้างยุติธรรม
David Moles

4

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

คุณ: สมมติว่าคุณต้องการทำ x คุณเรียกวิธีการ doX .. DEV: บอกฉันมากกว่านี้ .. อะไรคือข้อโต้แย้ง?

นี่คือสาธารณะ ...

คุณ: ใน doX ฉันเรียก ... DEV: โอ้โหข้อมูลมากเกินไปฉันไม่สนใจสิ่งนั้น ฉันแค่อยากรู้วิธีใช้งาน บอกอะไรฉันอีก

นี่เป็นส่วนตัว ...

คุณ: เมื่อ subclassing ฉันมี dox และ doY เรียก doIt ซึ่งทำ .. DEV: ใช่ฉันจะเรียน subclass บอกฉันที ...

สิ่งนี้ได้รับการคุ้มครอง ...

คุณ: ฉันจะไปเที่ยวพักผ่อนในอีกหนึ่งชั่วโมงฉันจะไปอีก 6 เดือนข้างหน้า บอสพูดว่าลูกสุนัขตัวนี้เป็นของคุณ! บาย. DEV: เดี๋ยวก่อนอย่าไปบอกฉันทุกอย่าง ...

นี่คือแพ็คเกจ

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

นี่คือการป้องกันส่วนตัว ...


3

สิ่งนี้มีอยู่แล้ว มันได้รับการคุ้มครอง

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

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


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

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

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