มีเหตุผลอะไรที่ดีที่จะห้ามการสืบทอดใน Java เช่นโดยใช้คลาสสุดท้ายหรือคลาสที่ใช้คอนสตรัคเตอร์แบบไม่มีพารามิเตอร์ตัวเดียว? อะไรคือเหตุผลที่ดีในการทำให้วิธีการเป็นที่สิ้นสุด?
มีเหตุผลอะไรที่ดีที่จะห้ามการสืบทอดใน Java เช่นโดยใช้คลาสสุดท้ายหรือคลาสที่ใช้คอนสตรัคเตอร์แบบไม่มีพารามิเตอร์ตัวเดียว? อะไรคือเหตุผลที่ดีในการทำให้วิธีการเป็นที่สิ้นสุด?
คำตอบ:
การอ้างอิงที่ดีที่สุดของคุณที่นี่คือรายการที่ 19 ของหนังสือยอดเยี่ยมของ Joshua Bloch "Effective Java" ที่เรียกว่า "การออกแบบและเอกสารสำหรับการสืบทอดไม่เช่นนั้นจะห้าม" (เป็นรายการที่ 17 ในรุ่นที่สองและรายการที่ 15 ในรุ่นแรก) คุณควรอ่านจริง ๆ แต่ฉันจะสรุป
ปฏิสัมพันธ์ของชั้นเรียนที่สืบทอดกับผู้ปกครองของพวกเขาสามารถที่น่าแปลกใจและไม่สามารถคาดเดาได้ถ้าบรรพบุรุษไม่ได้ถูกออกแบบมาให้สืบทอด
คลาสจึงควรมีสองแบบ:
คลาสที่ออกแบบมาเพื่อขยายและมีเอกสารเพียงพอที่จะอธิบายวิธีการทำ
คลาสที่ทำเครื่องหมายสุดท้าย
หากคุณกำลังเขียนรหัสภายในอย่างหมดจดนี่อาจจะเกินความเป็นจริงเล็กน้อย อย่างไรก็ตามความพยายามพิเศษที่เกี่ยวข้องในการเพิ่มอักขระห้าตัวไปยังไฟล์คลาสมีขนาดเล็กมาก หากคุณกำลังเขียนเพื่อใช้ภายในองค์กรเท่านั้นผู้เขียนรหัสในอนาคตสามารถลบคำว่า "ขั้นสุดท้าย" ออกได้ - คุณสามารถนึกได้ว่ามันเป็นคำเตือนว่า "ชั้นนี้ไม่ได้ออกแบบมาโดยคำนึงถึงมรดก"
คุณอาจต้องการทำให้วิธีการสุดท้ายเพื่อให้การเอาชนะชั้นเรียนไม่สามารถเปลี่ยนพฤติกรรมที่นับในวิธีอื่น ๆ วิธีการที่เรียกใน Constructor นั้นมักถูกประกาศให้ทราบขั้นสุดท้ายดังนั้นคุณจะไม่ได้รับความประหลาดใจอันไม่พึงประสงค์เมื่อสร้างวัตถุ
final
จะแนะนำว่าหนึ่งในหน้าที่ของฉันฉันโทรจากคอนสตรัคที่ควรจะ
เหตุผลหนึ่งที่ทำให้การเรียนเป็นขั้นสุดท้ายคือถ้าคุณต้องการบังคับให้มีการแต่งเพลงมากกว่าการสืบทอด สิ่งนี้เป็นที่ต้องการโดยทั่วไปในการหลีกเลี่ยงการมีเพศสัมพันธ์อย่างแน่นหนาระหว่างคลาส
มี 3 กรณีการใช้งานที่คุณสามารถไปหาวิธีสุดท้ายได้
จุดประสงค์ในการทำให้ชั้นเรียนสุดท้าย:
เพื่อให้ร่างกายไม่สามารถขยายชั้นเรียนเหล่านั้นและเปลี่ยนพฤติกรรมของพวกเขา
เช่นคลาส Wrapper Integer เป็นคลาสสุดท้าย หากคลาสนั้นไม่เป็นที่สิ้นสุดดังนั้นบุคคลใดก็ตามสามารถขยายจำนวนเต็มเป็นคลาสของตนเองและเปลี่ยนพฤติกรรมพื้นฐานของคลาสจำนวนเต็ม เพื่อหลีกเลี่ยงปัญหานี้ java จึงสร้างคลาส wrapper ทั้งหมดเป็นคลาสสุดท้าย
DerivedInteger
ก็ยังไม่เปลี่ยนคลาส Integer ดั้งเดิมและใครก็ตามที่ใช้งานDerivedInteger
จะต้องรับความเสี่ยงด้วยตัวเองดังนั้นฉันจึงยังไม่เข้าใจสาเหตุที่เป็นปัญหา
คุณอาจต้องการสร้างวัตถุที่ไม่เปลี่ยนรูปแบบ ( http://en.wikipedia.org/wiki/Immutable_object ) คุณอาจต้องการสร้างซิงเกิลตัน ( http://en.wikipedia.org/wiki/Singleton_pattern ) หรือคุณอาจต้องการ เพื่อป้องกันไม่ให้ใครบางคนเอาชนะวิธีการด้วยเหตุผลของประสิทธิภาพความปลอดภัยหรือความปลอดภัย
การรับมรดกเป็นเหมือนเลื่อยลูกโซ่ - ทรงพลังมาก แต่น่ากลัวในมือที่ไม่ดี ไม่ว่าคุณจะออกแบบคลาสที่จะสืบทอดมา (ซึ่งสามารถจำกัดความยืดหยุ่นและใช้เวลานาน) หรือคุณควรห้ามคลาสนั้น
ดูผลบังคับใช้ Java รายการรุ่นที่ 2 วันที่ 16 และ 17 หรือโพสต์บล็อกของฉัน"ภาษีมรดก"
อืม ... ฉันนึกถึงสองสิ่ง:
คุณอาจมีคลาสที่เกี่ยวข้องกับปัญหาด้านความปลอดภัยบางอย่าง โดย subclassing มันและให้ระบบของคุณในเวอร์ชัน subclassed นั้นผู้โจมตีสามารถหลีกเลี่ยงข้อ จำกัด ด้านความปลอดภัย เช่นแอปพลิเคชันของคุณอาจสนับสนุนปลั๊กอินและหากปลั๊กอินสามารถเพียงแค่คลาสย่อยที่เกี่ยวข้องกับการรักษาความปลอดภัยชั้นเรียนของคุณก็สามารถใช้เคล็ดลับนี้เพื่อลักลอบใช้เวอร์ชันย่อยของคลาสนั้น อย่างไรก็ตามนี่เป็นสิ่งที่ Sun ต้องจัดการเกี่ยวกับแอปเพล็ตและสิ่งที่คล้ายกันอาจไม่ใช่กรณีจริง
สิ่งที่เหมือนจริงมากขึ้นคือการหลีกเลี่ยงวัตถุที่ไม่แน่นอน เช่นเนื่องจาก Strings ไม่เปลี่ยนรูปรหัสของคุณสามารถอ้างอิงได้อย่างปลอดภัย
String blah = someOtherString;
แทนการคัดลอกสตริงก่อน อย่างไรก็ตามหากคุณสามารถ subclass String คุณสามารถเพิ่มวิธีการที่อนุญาตให้มีการแก้ไขค่าสตริงตอนนี้ไม่มีรหัสใด ๆ ที่สามารถพึ่งพาได้อีกต่อไปว่าสตริงจะยังคงเหมือนเดิมถ้ามันเพิ่งคัดลอกสตริงดังกล่าวข้างต้นแทนมันจะต้องทำซ้ำ เชือก
นอกจากนี้หากคุณกำลังเขียนคลาสโอเพนซอร์ซเชิงพาณิชย์คุณอาจไม่ต้องการให้ผู้คนสามารถเปลี่ยนการทำงานลงได้โดยเฉพาะอย่างยิ่งถ้าคุณต้องการให้การสนับสนุนและผู้คนได้แทนที่วิธีการของคุณและบ่นว่าการโทรนั้นให้ ผลลัพธ์ที่ไม่คาดคิด
ถ้าคุณทำเครื่องหมายคลาสและเมธอดเป็นขั้นสุดท้ายคุณอาจสังเกตเห็นว่าประสิทธิภาพเพิ่มขึ้นเล็กน้อยเนื่องจากรันไทม์ไม่จำเป็นต้องค้นหาเมธอดคลาสที่เหมาะสมเพื่อเรียกใช้ออบเจกต์ที่กำหนด วิธีการที่ไม่ใช่ขั้นสุดท้ายถูกทำเครื่องหมายเป็นเสมือนเพื่อให้สามารถขยายได้อย่างถูกต้องหากจำเป็นวิธีการขั้นสุดท้ายสามารถเชื่อมโยงโดยตรงหรือรวบรวมแบบอินไลน์ในชั้นเรียน
เพื่อหยุดยั้งผู้คนจากการทำสิ่งต่าง ๆ ที่อาจสร้างความสับสนให้ตนเองและผู้อื่น ลองนึกภาพห้องสมุดฟิสิกส์ที่คุณมีค่าคงที่หรือการคำนวณอยู่บ้าง หากไม่มีการใช้คำหลักสุดท้ายใครบางคนสามารถเข้ามาใหม่และกำหนดค่าการคำนวณพื้นฐานหรือค่าคงที่ที่ไม่ควรเปลี่ยน
คุณต้องการทำให้วิธีการสุดท้ายเพื่อให้เอาชนะชั้นเรียนจะไม่เปลี่ยนพฤติกรรมของมัน เมื่อคุณต้องการที่จะสามารถเปลี่ยนพฤติกรรมทำให้วิธีการสาธารณะ เมื่อคุณแทนที่วิธีสาธารณะมันสามารถเปลี่ยนได้