โดยการแสดงถึงเมธอดคลาสด้วยตัวดัดแปลง
final
เราหมายความว่าไม่มีคลาสที่ได้รับมาใด ๆ ที่สามารถแทนที่เมธอดนี้ได้โดยการเปลี่ยนการใช้งานภายใน กล่าวอีกนัยหนึ่ง เรากำลังพูดถึงเวอร์ชันสุดท้ายของวิธีการนี้ ชั้นเรียนโดยรวมสามารถทำเครื่องหมายfinal
เป็น
final class NoExtending {
// …
}
คลาสที่ถูกทำเครื่องหมายว่าfinal
ไม่สามารถสืบทอดได้ และวิธีการทั้งหมดของคลาสนั้นจะได้รับคุณสมบัติทางfinal
อ้อม การใช้คุณลักษณะfinal
ในการประกาศคลาสและวิธีการสามารถเพิ่มระดับความปลอดภัยของโค้ดได้ ถ้าคลาสติดตั้ง modifier final
จะไม่มีใครสามารถขยายคลาสได้และอาจผิดสัญญาในกระบวนการนี้ หากป้ายfinal
แสดงถึงวิธีการ คุณสามารถไว้วางใจการใช้งานภายในได้อย่างเต็มที่ในทุกสถานการณ์โดยไม่ต้องกลัว "การปลอมแปลง" เหมาะสมที่จะใช้final
ตัวอย่างเช่น ในการประกาศวิธีการที่ต้องมีการตรวจสอบรหัสผ่านที่ผู้ใช้ป้อนเพื่อให้แน่ใจว่ามีการดำเนินการที่แน่นอนตามที่วิธีการนั้นตั้งใจไว้แต่แรก ผู้โจมตีที่เป็นไปได้จะไม่สามารถเปลี่ยนการใช้งานดั้งเดิมของวิธีการดังกล่าวได้โดยการ "ลื่นไถล" เข้าไปในโปรแกรมในเวอร์ชันที่ถูกแทนที่ซึ่งกล่าวจะส่งกลับค่าจริงเสมอซึ่งบ่งชี้ว่าการลงทะเบียนผู้ใช้สำเร็จโดยไม่คำนึงถึงรหัสผ่านใด เขาเข้ามาจริงๆ คุณมีสิทธิ์ (หากสถานการณ์เฉพาะเอื้ออำนวย) ที่จะประกาศให้final
ชั้นเรียนทั้งหมดเป็นชั้นเรียน วิธีValidatePassword
จะได้คุณสมบัติเดียวกันทางอ้อม การใช้ตัวแก้ไขfinal
ในการประกาศวิธีการหรือคลาสทำให้เกิดข้อจำกัดที่ร้ายแรงเกี่ยวกับความเป็นไปได้ในการใช้งานและพัฒนาโค้ดต่อไป การใช้final
เมธอดในการประกาศเป็นตัวบ่งชี้ที่แน่นอนว่าการนำเมธอดไปใช้งานนั้นมีอยู่ในตัวเองและครบถ้วนสมบูรณ์ โปรแกรมเมอร์คนอื่นๆ ที่ต้องการใช้คลาสของคุณโดยขยายฟังก์ชันให้เหมาะกับความต้องการของตนเอง จะถูกจำกัดในการเลือกวิธีการเพื่อให้บรรลุเป้าหมายหรือถูกกีดกันโดยสิ้นเชิง ด้วยการทำเครื่องหมายfinal
ชั้นเรียนโดยรวม คุณจะปิดการใช้งานความสามารถในการสืบทอดของชั้นเรียน และมีแนวโน้มที่จะลดประโยชน์ของชั้นเรียนที่มีต่อผู้อื่นอย่างมาก เมื่อคุณกำลังจะใช้ตัวแก้ไข ตรวจสอบfinal
ให้แน่ใจว่าคุณพร้อมสำหรับการเสียสละดังกล่าวหรือไม่ และคุ้มค่าที่จะทำหรือไม่ ในหลายกรณี เพื่อให้บรรลุระดับความปลอดภัยของโค้ดที่เพียงพอ ไม่จำเป็นต้องกำหนดทั้งคลาสเป็นfinal
- ค่อนข้างเป็นไปได้ที่จะรักษาความสามารถในการขยายของคลาสโดยการทำเครื่องหมายfinal
เฉพาะองค์ประกอบโครงสร้างที่ "สำคัญ" ด้วยตัวดัดแปลง ในกรณีนี้ คุณจะปล่อยให้ฟังก์ชันหลักของคลาสไม่บุบสลายและในขณะเดียวกันก็อนุญาตให้มีการสืบทอดด้วยการเพิ่มสมาชิกใหม่ แต่ไม่มีการกำหนดนิยาม "เก่า" ใหม่ แน่นอนว่าฟิลด์ที่เข้าถึงโดยโค้ดของวิธีการนั้นfinal
จะต้องถูกกำหนดให้เป็นอย่างfinal
ใดอย่างหนึ่งprivate
เนื่องจากไม่เช่นนั้นคลาสที่ได้รับจะสามารถเปลี่ยนเนื้อหาได้ ซึ่งส่งผลต่อพฤติกรรมของวิธีการที่เกี่ยวข้อง ผลกระทบอีกประการหนึ่งของการใช้ตัวปรับแต่งนั้นfinal
สัมพันธ์กับการลดความซับซ้อนของปัญหาการเพิ่มประสิทธิภาพโค้ดที่แก้ไขโดยคอมไพเลอร์ นี่คือสิ่งที่เกิดขึ้นเมื่อมีการเรียกใช้วิธีการที่ไม่ได้ทำเครื่องหมายว่าfinal
ระบบรันไทม์จะกำหนดคลาสที่แท้จริงของออบเจ็กต์ เชื่อมโยงการโทรกับโค้ดที่เหมาะสมที่สุดจากกลุ่มของวิธีการโอเวอร์โหลด และโอนการควบคุมไปยังโค้ดนั้น แต่ถ้า ตัวอย่างเช่น วิธีการgetName
ในชั้นเรียนตัวอย่างAttr
ที่กล่าวถึงก่อนหน้านี้ถูกกำหนดเป็นfinal
การดำเนินการของการเรียกมันอาจจะง่ายขึ้นอย่างเห็นได้ชัด ในกรณีที่ไม่สำคัญที่สุด เช่น กรณีที่เกี่ยวข้องgetName
คอมไพเลอร์สามารถแทนที่การเรียกเมธอดด้วยโค้ดเนื้อหาได้ กลไกนี้เรียกว่าโค้ดอินไลน์ เมื่อใช้วิธีการเวอร์ชันอินไลน์getName
นิพจน์สองรายการต่อไปนี้จะถูกดำเนินการเหมือนกันทุกประการ:
system.out.println("id = " + rose.name);
system.out.println("id = " + rose.getName());
แม้ว่านิพจน์ข้างต้นจะเทียบเท่ากัน แต่นิพจน์ที่สองยังคงมีข้อได้เปรียบ เนื่องจากวิธีนี้getName
ช่วยให้คุณกำหนดคุณสมบัติแบบอ่านอย่างเดียวให้กับฟิลด์ชื่อได้ และโค้ดคลาสจะมีระดับนามธรรมในระดับหนึ่ง ซึ่งช่วยให้คุณเปลี่ยนนิพจน์ได้อย่างอิสระมากขึ้น การดำเนินการชั้นเรียน คอมไพเลอร์สามารถใช้รูปแบบการปรับให้เหมาะสมเดียวกันนี้กับเมธอดprivate
และstatiс
เนื่องจากไม่อนุญาตให้มีการแทนที่ การใช้ตัวแก้ไขfinal
ในการประกาศคลาสยังทำให้การดำเนินการตรวจสอบบางประเภทมีประสิทธิภาพมากขึ้น ในกรณีนี้ การดำเนินการดังกล่าวหลายอย่างสามารถดำเนินการได้ในขั้นตอนการคอมไพล์แล้ว ดังนั้นข้อผิดพลาดที่อาจเกิดขึ้นจึงถูกตรวจพบเร็วกว่านั้นมาก หากคอมไพลเลอร์พบการอ้างอิงถึงคลาสในข้อความต้นฉบับfinal
ก็สามารถ "แน่ใจ" ว่าวัตถุที่เกี่ยวข้องนั้นเป็นประเภทที่ระบุ คอมไพเลอร์สามารถระบุตำแหน่งที่คลาสครอบครองในลำดับชั้นโดยรวมของคลาสได้ทันที และตรวจสอบว่ามีการใช้อย่างถูกต้องหรือไม่ หากfinal
ไม่ได้ใช้ตัวแก้ไข การตรวจสอบที่เกี่ยวข้องจะดำเนินการเฉพาะในขั้นตอนการทำงานของโปรแกรมเท่านั้น แบบฝึกหัดที่ 3.4 ขอแนะนำให้รวมตัวแก้ไข ขั้นสุดท้าย ไว้ใน การประกาศวิธีการ (และหากเป็นเช่นนั้น ตัวแก้ไขใด) ของ ประเภท ยานพาหนะและผู้โดยสาร ลิงก์ไปยังแหล่งที่มาดั้งเดิม: http://src-code.net/metody-i-klassy-final-java
GO TO FULL VERSION