ฉันสับสนเล็กน้อยเกี่ยวกับคำว่า "แพ็กเกจส่วนตัว" ที่เอกสารบางส่วนใช้ร่วมกับการใช้ "การเข้าถึงเริ่มต้น" การเข้าถึงแบบแพ็กเกจส่วนตัวและค่าเริ่มต้นไม่ตรงกันกับการป้องกันหรือไม่?
ฉันสับสนเล็กน้อยเกี่ยวกับคำว่า "แพ็กเกจส่วนตัว" ที่เอกสารบางส่วนใช้ร่วมกับการใช้ "การเข้าถึงเริ่มต้น" การเข้าถึงแบบแพ็กเกจส่วนตัวและค่าเริ่มต้นไม่ตรงกันกับการป้องกันหรือไม่?
คำตอบ:
ใช่มันเกือบจะเหมือนกัน ตัวปรับแต่งที่ได้รับการป้องกันระบุว่าสมาชิกสามารถเข้าถึงได้ภายในแพ็กเกจของตนเองเท่านั้น (เช่นเดียวกับแพ็กเกจส่วนตัว) และนอกจากนี้โดยคลาสย่อยของคลาสในแพ็กเกจอื่น
public static final
สำหรับวิธีการคือpublic abstract
สำหรับ enum หรือคำอธิบายประกอบคือpublic
และสำหรับคลาสนั้นpublic static
ตัวแก้ไขการเข้าถึง "ค่าเริ่มต้น" (ตัวแก้ไขการเข้าถึงที่ไม่ได้ระบุไว้อย่างชัดเจน) คือ "package-private" ซึ่งหมายความว่ามีเพียงสิ่งต่างๆในแพ็กเกจเดียวกันเท่านั้นที่สามารถเข้าถึงได้ อย่างไรก็ตามการอยู่ในแพ็คเกจเดียวกันไม่ได้หมายความว่าไม่มีอะไรเกี่ยวกับความสัมพันธ์ทางมรดกระหว่างคลาส - มันเป็นหลักการตั้งชื่อเท่านั้น
"ได้รับการป้องกัน" หมายความว่าไม่เพียง แต่คลาสในแพ็กเกจเดียวกันเท่านั้น แต่ยังรวมถึงคลาสย่อยด้วย (ไม่ว่าคลาสย่อยเหล่านั้นจะอยู่ในแพ็กเกจใด) ก็จะสามารถเข้าถึงได้
การเข้าถึงดีฟอลต์สำหรับคลาสคือแพ็กเกจส่วนตัวอย่างไรก็ตามการเข้าถึงดีฟอลต์สำหรับสมาชิกอินเทอร์เฟซเป็นแบบสาธารณะ
เช่น
public interface I {
int A = 1;
// same as
public static final int A = 1;
void method();
// same as
public abstract void method();
class C { }
// same as
public static class C { }
}
กฎการเข้าถึงเริ่มต้นสำหรับอินเทอร์เฟซไม่เหมือนกับคลาส
Package-private และ default access เป็นคำพ้องความหมาย อ็อบเจ็กต์ยังสามารถเข้าถึงสมาชิกที่ได้รับการป้องกันของอ็อบเจ็กต์ที่มีคลาสอยู่ในแพ็กเกจเดียวกัน ออบเจ็กต์ยังสามารถเข้าถึงสมาชิกที่ได้รับการป้องกันของคลาสระดับสูงโดยไม่มีเงื่อนไขเกี่ยวกับแพ็กเกจ เป็นตัวอย่างที่เป็นรูปธรรม:
package ab;
class A {
protected void foo() {}
void dd(){}
}
class C {
void aa(){
A a = new A();
a.foo(); //legal
a.dd(); //legal
}
}
package sub;
class D extends A{
void ac(){
foo(); //legal ..
dd(); //illegal.. because dd has default access..
}
class E {
void ee(){
A a = new A();
a.foo(); //illegal
a.dd(); //illegal
}
'แพ็กเกจส่วนตัว' และการเข้าถึงเริ่มต้นจะเหมือนกัน ในคอมไพเลอร์รุ่นแรก ๆ ประมาณ 1.1.2 / 3 'แพ็กเกจ' เป็นตัวปรับแต่งที่อนุญาต แต่ถูกละเว้นซึ่งมีความหมายเหมือนกับไม่มีตัวปรับเปลี่ยนนั่นคือ 'แพ็กเกจส่วนตัว' หลังจากนั้นไม่นานก็มีแฟชั่นสั้น ๆ สำหรับใส่/*package*/
(เป็นข้อคิดเห็น) ในสถานการณ์เช่นนี้ ในทำนองเดียวกันในเวลานั้นคุณสามารถประกาศสิ่งต่างๆเช่นคลาสที่ซิงโครไนซ์ได้แม้ว่าจะไม่มีผลทางความหมายที่แท้จริงอีกครั้ง
ทั้งสองอย่างไม่เหมือนกับ 'ป้องกัน' ซึ่งขยายไปยังคลาสที่ได้รับในแพ็คเกจอื่น ๆ
- 6.6.5 ตัวอย่าง: Default-Access Fields, Methods และ Constructorsหากไม่มีการระบุตัวแก้ไขการเข้าถึง public, protected หรือ private ไว้สมาชิกคลาสหรือตัวสร้างจะสามารถเข้าถึงได้ตลอดทั้งแพ็กเกจที่มีการประกาศคลาสที่คลาสนั้น ๆ มีการประกาศสมาชิก แต่สมาชิกคลาสหรือตัวสร้างไม่สามารถเข้าถึงได้ในแพ็คเกจอื่น
ถ้าคลาสพับลิกมีเมธอดหรือตัวสร้างที่มีการเข้าถึงดีฟอลต์เมธอดหรือตัวสร้างนี้จะไม่สามารถเข้าถึงหรือสืบทอดโดยคลาสย่อยที่ประกาศนอกแพ็กเกจนี้
defaultและpackage-privateทั้งสองเหมือนกันซึ่งหมายความว่าทั้งสองคลาสสามารถใช้ได้จนกว่าจะอยู่ในแพ็คเกจเดียวกัน
แพคเกจและเอกชนระยะจริงจะเรียกว่าโดยความหมายของเอกชนที่ปรับแต่งเป็นส่วนตัวหมายความว่ามันจะใช้ได้เฉพาะในชั้นเดียวกันและไม่มีชั้นเรียนอื่น ๆ หรือ subclasses สามารถเข้าถึงได้ภายในแพคเกจเดียวกันหรือไม่มี
ดังนั้นแพคเกจส่วนตัววิธีการเช่นเดียวกับการเริ่มต้น