ส่วนตัว vs ได้รับการป้องกัน - การเปิดเผยที่ดีเกี่ยวกับการปฏิบัติที่เกี่ยวข้อง [ปิด]


145

ฉันค้นหามาแล้วและฉันรู้ความแตกต่างทางทฤษฎี

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

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

จนถึงตอนนี้เพื่อรักษาแนวคิดของการสืบทอดและ polymorphism ฉันใช้publicสำหรับทุกสิ่งที่ควรเข้าถึงได้จากภายนอก (เช่นตัวสร้างและการทำงานของคลาสหลัก) และprotectedสำหรับวิธีการภายใน (ตรรกะวิธีการช่วยเหลือ ฯลฯ ) ฉันกำลังติดตามใช่ไหม?

(โปรดทราบว่าคำถามนี้มีไว้สำหรับฉัน แต่ยังใช้สำหรับการอ้างอิงในอนาคตเนื่องจากฉันไม่ได้เห็นคำถามเช่นนี้ดังนั้น)


33
มันสำคัญไหม ภาษาใดก็ตามที่มีการสนับสนุน OOP มีข้อกังวลใจนี้ ฉันเกิดขึ้นกับโปรแกรมใน PHP แต่ฉันคิดว่าคำถามนี้ใช้ได้กับภาษาที่รองรับ OOP
Madara's Ghost

2
โอเคยุติธรรมพอเพียงแค่สงสัยว่าคุณลืมแท็กหรือไม่ ตอนนี้ฉันเห็นแท็ก oop
Paul Bellora

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

1
ทันใดนั้นความแตกต่างระหว่างการป้องกันและส่วนตัวดูเหมือนชัดเจน ใช้การป้องกันหากคลาสย่อยจะใช้เมธอด / ตัวแปรมิฉะนั้นจะใช้ไพรเวต โดยเฉพาะถ้าคลาสย่อยจะต้องกำหนดตัวแปรส่วนตัวที่คล้ายกันอีกครั้งในพาเรนต์ให้ทำการป้องกัน
iPherian

มีตัวระบุการเข้าถึงอื่นinternalในภาษา C # ซึ่ง จำกัด ระดับการเข้าถึงของคลาสหรือสมาชิกภายในชุดประกอบแบบฟิสิคัล แม้ว่าฉันไม่แน่ใจเกี่ยวกับการสนับสนุนหรือสิ่งที่คล้ายกันในภาษาอื่น ๆ
RBT

คำตอบ:


128

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

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

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


1
คำถามจริงที่นี่เป็นเรื่องเกี่ยวกับprivatevs protectedฉันจะต้องได้รับมรดกเมื่อใดและเมื่อใด ฉันไม่สามารถบอกได้ว่าผู้ใช้บางครั้งในอนาคตต้องการที่จะเข้าร่วมชั้นเรียนของฉันและขยายเวลา ...
Madara's Ghost

16
ดีคำถามไม่ใช่สิ่งที่ผู้ใช้ต้องการแทนที่คำถามคือสิ่งที่คุณต้องการอนุญาตให้ถูกแทนที่ โดยปกติแล้วจะช่วยในการสลับข้างและพยายามคิดว่า: ถ้าฉันใช้คลาสนั้นและสร้างคลาสย่อยฉันจะต้องลบล้างอะไรบ้าง บางครั้งผู้ใช้คนอื่นจะยังคงพลาดอยู่ ...
Thorsten Dittmar

3
เขตข้อมูลที่มีการป้องกันเป็นการปฏิบัติที่ไม่ดีในการสืบทอด! . โปรดระวัง นี่คือเหตุผล
RBT

4
เขตข้อมูลส่วนตัวไม่ดีในทางปฏิบัติในการสืบทอด! (เกินความจริง) โปรดอ่านคำตอบของฉัน
Larry

6
ความคิดเห็นควบคุมประหลาดทั่วไป
bruno desthuilliers

58

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

ภูมิปัญญาเก่าแก่

"ทำเครื่องหมายเป็นส่วนตัวเว้นแต่คุณจะมีเหตุผลที่ดีที่จะไม่"

ทำให้รู้สึกในวันที่มันถูกเขียนก่อนที่โอเพนซอร์สครอบงำพื้นที่ห้องสมุดนักพัฒนาและ VCS / การพึ่งพา mgmt กลายเป็นความร่วมมือที่มากเกินไปต้องขอบคุณ Github, Maven และอื่น ๆ จากนั้นก็มีเงินที่ต้องทำโดยการ จำกัด วิธีที่ห้องสมุดสามารถนำไปใช้ประโยชน์ได้ ฉันใช้เวลาในช่วง 8 หรือ 9 ปีแรกของอาชีพการงานของฉันอย่างเคร่งครัด

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

คุณเคย:

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

นี่เป็นสามข้อแก้ตัวที่ใหญ่ที่สุดที่ฉันเคยได้ยินเกี่ยวกับวิธีการทำเครื่องหมายส่วนตัวโดยค่าเริ่มต้น:

หาเหตุผลเข้าข้างตนเอง # 1: มันไม่ปลอดภัยและไม่มีเหตุผลที่จะแทนที่วิธีการเฉพาะ

ฉันไม่สามารถนับจำนวนครั้งที่ฉันคิดผิดเกี่ยวกับว่าจะมีความจำเป็นต้องแทนที่วิธีการเฉพาะที่ฉันเขียนหรือไม่ เมื่อทำงานกับ libs โอเพนซอร์สยอดนิยมหลายอย่างฉันได้เรียนรู้วิธีที่ยากลำบากในการทำเครื่องหมายค่าใช้จ่ายส่วนตัว มันมักจะกำจัดวิธีแก้ปัญหาในทางปฏิบัติเพียงอย่างเดียวในการแก้ปัญหาที่ไม่เหมาะสมหรือใช้เคส ในทางกลับกันฉันไม่เคยใช้วิธีการพัฒนามืออาชีพมานานกว่า 16 ปีเสียใจที่ทำเครื่องหมายวิธีการป้องกันแทนส่วนตัวด้วยเหตุผลที่เกี่ยวข้องกับความปลอดภัยของ API เมื่อนักพัฒนาเลือกที่จะขยายชั้นเรียนและแทนที่วิธีการพวกเขารู้ตัวว่า "ฉันรู้ว่าฉันกำลังทำอะไรอยู่" และเพื่อประโยชน์ในการผลิตที่ควรจะเพียงพอ ระยะเวลา หากเป็นอันตรายให้บันทึกไว้ในคลาส / วิธี Javadocs ไม่เพียงแค่ปิดประตูอย่างมิดชิด

วิธีการทำเครื่องหมายที่ป้องกันโดยค่าเริ่มต้นคือการลดปัญหาหนึ่งในประเด็นสำคัญในการพัฒนา SW สมัยใหม่: ความล้มเหลวของจินตนาการ

หาเหตุผลเข้าข้างตนเอง # 2: มันช่วยให้สาธารณะ API / Javadocs สะอาด

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

หาเหตุผลเข้าข้างตนเอง # 3: ซอฟต์แวร์ของฉันเป็นเชิงพาณิชย์และฉันจำเป็นต้อง จำกัด การใช้งาน

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

ไม่เคยพูดไม่เคย

ฉันไม่ได้บอกว่าไม่เคยทำเครื่องหมายวิธีการส่วนตัว ฉันกำลังบอกว่ากฎง่ายๆคือ "ทำวิธีการป้องกันเว้นแต่จะมีเหตุผลที่ดีที่จะไม่"

คำแนะนำนี้เหมาะที่สุดสำหรับผู้ที่ทำงานในห้องสมุดหรือโครงการขนาดใหญ่ที่แบ่งเป็นโมดูล สำหรับโปรเจกต์ขนาดเล็กหรือขนาดใหญ่มันไม่ได้มีความสำคัญมากนักเนื่องจากคุณสามารถควบคุมโค้ดทั้งหมดได้และมันก็ง่ายที่จะเปลี่ยนระดับการเข้าถึงของโค้ดของคุณถ้า / เมื่อคุณต้องการ ถึงแม้ว่าฉันจะยังคงให้คำแนะนำเดียวกัน :-)


Wrt ของคุณRationalization # 1- เมื่อฉันทำเครื่องหมายสิ่งที่ได้รับการป้องกันฉันเลือกที่จะทำอย่างชัดเจนเนื่องจากฉันรู้สึกว่าพฤติกรรมนี้ไม่เป็นที่สิ้นสุดและอาจเป็นกรณีที่คลาสลูกของฉันต้องการจะแทนที่ หากฉันไม่แน่ใจดังนั้นฉันจะทำให้เป็นส่วนตัวโดยค่าเริ่มต้น พิเศษในภาษาเช่น C # ซึ่งใช้วิธีการที่ไม่ใช่เสมือนจริงโดยค่าเริ่มต้นการเพิ่มตัวระบุการเข้าถึงที่ได้รับการป้องกันนั้นไม่สมเหตุสมผลคุณต้องเพิ่มทั้งสองvirtualและprotectedคำหลักเพื่อให้เจตนาของคุณชัดเจน นอกจากนี้ผู้คนยังต้องการความเชื่อมโยงกับการสืบทอดดังนั้นprotectedค่าเริ่มต้นจึงยากต่อการเข้าใจ
RBT

4
การรวมกันของคำหลักที่จำเป็นในการทำให้วิธีการ overridable เป็นรายละเอียดภาษา IMHO อาร์กิวเมนต์ตัวนับที่ฉันนำเสนอต่อการหาเหตุผลเข้าข้างตนเอง # 1 มีจุดมุ่งหมายอย่างตรงไปตรงมาในกรณีที่คุณพูดถึง "ถ้าฉันไม่แน่ใจ ... " พูดจริงถ้าคุณไม่สามารถคิดเหตุผลว่าทำไมมันจะเป็นอันตรายแล้วมีมากขึ้นที่จะได้รับโดยการเลือกสำหรับการขยาย เมื่อคุณพูดว่า 'การเชื่อมโยง' ฉันถือว่ามันเป็นคำพ้องความหมายสำหรับการเรียบเรียงซึ่งในกรณีนี้ฉันไม่เห็นว่ามันมีความหมายใด ๆ
Nick

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

1
ตกลง. ฉันแค่ต้องการปรับแต่ง BufferedReader ของ Java เพื่อจัดการตัวคั่นบรรทัดที่กำหนดเอง ขอบคุณเขตข้อมูลส่วนตัวฉันต้องโคลนทั้งคลาสแทนที่จะขยายและแทนที่ readLine ()
Ron Dunn

21

หยุดการใช้สนามส่วนตัวในทางที่ผิด !!!

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

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

มีสองกรณีที่คุณต้องการขยายชั้นเรียน:

  • คุณต้องการเพิ่มฟังก์ชันพิเศษให้กับคลาสพื้นฐาน
  • คุณต้องการแก้ไขคลาสที่มีอยู่ซึ่งอยู่นอกแพ็คเกจปัจจุบัน (ในบางไลบรารี)

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

พิจารณาห้องสมุดง่าย ๆ ที่จำลองรถยนต์:

class Car {
    private screw;
    public assembleCar() {
       screw.install();
    };
    private putScrewsTogether() {
       ...
    };
}

ผู้เขียนห้องสมุดคิดว่า: ไม่มีเหตุผลที่ผู้ใช้ห้องสมุดของฉันต้องเข้าถึงรายละเอียดการติดตั้งassembleCar()ใช่ไหม มาทำเครื่องหมายสกรูว่าเป็นส่วนตัว

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

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

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

ฉันสนับสนุนคำตอบของนิคอย่างมาก


2
การใช้ฟิลด์ส่วนตัวส่วนใหญ่เป็นการบอกว่าการสืบทอดนั้นเป็นนามธรรมที่ไม่ถูกต้องในการปรับเปลี่ยนพฤติกรรมบางอย่างของคลาส / วัตถุ (หากใช้อย่างมีสติ) การเปลี่ยนแปลงโดยปกติจะเป็นการละเมิด LSP โดยไม่แจ้งเตือนเมื่อมีการเปลี่ยนแปลงพฤติกรรมโดยไม่มีการเปลี่ยนแปลง API คำตอบที่ดี +1
Ghost ของ Madara เมื่อ

สั่งสอน! ส่วนตัวคือความหายนะของการมีอยู่ของฉันเมื่อพยายามเขียน mod Minecraft ไม่มีอะไรน่ารำคาญไปกว่าการใช้ Reflection หรือ ASM เพื่อแก้ไขปัญหานั้น
RecursiveExceptionException

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

16

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

  1. ทำให้คลาสทั้งหมดจบลงเว้นแต่ว่าคุณจะต้องการคลาสย่อยเหล่านั้นในทันที
  2. ทำให้วิธีการทั้งหมดเป็นขั้นสุดท้ายเว้นแต่คุณจะต้อง subclass และแทนที่พวกเขาทันที
  3. ทำพารามิเตอร์เมธอดทั้งหมดให้เป็นที่สุดเว้นแต่คุณจำเป็นต้องเปลี่ยนพารามิเตอร์ภายในเนื้อความของเมธอดซึ่งค่อนข้างน่าอึดอัดใจเกือบตลอดเวลา

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

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

ข้อจำกัดความรับผิดชอบ: ฉันไม่ได้เขียนโปรแกรมใน Java :)


2
ในการชี้แจง: A final classใน Java เป็นคลาสที่ไม่สามารถสืบทอดได้ A final methodไม่เสมือนคือไม่สามารถ overridable โดย subclass (วิธี Java เป็นเสมือนโดยค่าเริ่มต้น) A final field/parameter/variableเป็นการอ้างอิงตัวแปรที่เปลี่ยนแปลงไม่ได้ (ในแง่ที่ว่ามันไม่สามารถแก้ไขได้หลังจากที่มันถูกเริ่มต้น)
M.Stramm

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

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

7

คุณจะใช้privateเมื่อใดและจะใช้เมื่อprotectedใด

มรดกเอกชนอาจจะคิดว่าการดำเนินการในแง่ของความสัมพันธ์มากกว่าIS-Aความสัมพันธ์ กล่าวง่ายๆว่าอินเตอร์เฟสภายนอกของคลาสที่รับช่วงนั้นไม่มีความสัมพันธ์ (มองเห็นได้) กับคลาสที่สืบทอดมาซึ่งจะใช้การprivateสืบทอดเพียงเพื่อใช้ฟังก์ชันการทำงานที่คล้ายกันซึ่งคลาสพื้นฐานมอบให้

ไม่เหมือนมรดกส่วนตัว ป้องกันการสืบทอดเป็นรูปแบบที่ จำกัด ของการสืบทอดซึ่งในชั้นเรียนที่ได้รับIS-Aประเภทของชั้นฐานและมันต้องการที่จะ จำกัด การเข้าถึงของสมาชิกที่ได้รับเพียงชั้นที่ได้รับ


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

2
กระบวนการคิดที่น่าสนใจ - มรดกเอกชน @shawnhcorey ขอบคุณที่ทำให้ชัดเจนว่ามีการชี้ไปที่การเชื่อมโยงความสัมพันธ์HAS-A (ซึ่งอาจเป็นการรวมตัวกันหรือการจัดองค์ประกอบ) ฉันรู้สึกว่าโพสต์นี้ควรได้รับการอัปเดตเพื่อให้ความกระจ่างเหมือนกัน
RBT

1

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

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