คุณอาจพบว่าตัวเองอยู่ในฐานะที่จะคิดที่จะทำให้วิธีการคงที่เป็นขั้นสุดท้ายโดยพิจารณาสิ่งต่อไปนี้:
มีคลาสต่อไปนี้:
class A {
static void ts() {
System.out.print("A");
}
}
class B extends A {
static void ts() {
System.out.print("B");
}
}
ตอนนี้วิธีที่ 'ถูกต้อง' ในการเรียกวิธีการเหล่านี้จะเป็น
A.ts();
B.ts();
ซึ่งจะส่งผลให้AB
แต่คุณสามารถเรียกใช้เมธอดบนอินสแตนซ์ได้:
A a = new A();
a.ts();
B b = new B();
b.ts();
ซึ่งจะส่งผลAB
เช่นกัน
พิจารณาสิ่งต่อไปนี้:
A a = new B();
a.ts();
A
ที่จะพิมพ์ B
ที่อาจทำให้คุณประหลาดใจตั้งแต่คุณเป็นจริงมีวัตถุของคลาส แต่เนื่องจากคุณกำลังเรียกมันจากการอ้างอิงจากประเภทนี้ก็จะเรียกA
A.ts()
คุณสามารถพิมพ์B
โดยใช้รหัสต่อไปนี้:
A a = new B();
((B)a).ts();
B
ในทั้งสองกรณีวัตถุที่คุณมีความเป็นจริงจากชั้นเรียน แต่ขึ้นอยู่กับตัวชี้ที่ชี้ไปที่วัตถุคุณจะเรียกใช้วิธีการจากA
หรือจากB
หรือจาก
สมมติว่าคุณเป็นผู้พัฒนาคลาสA
และต้องการอนุญาตการแบ่งคลาสย่อย แต่คุณต้องการเมธอดts()
เมื่อใดก็ตามที่ถูกเรียกแม้กระทั่งจากคลาสย่อยนั่นคือสิ่งที่คุณต้องการให้ทำและไม่ถูกซ่อนโดยเวอร์ชันคลาสย่อย จากนั้นคุณสามารถสร้างfinal
และป้องกันไม่ให้ซ่อนอยู่ในคลาสย่อย และคุณมั่นใจได้ว่าโค้ดต่อไปนี้จะเรียกใช้เมธอดจากคลาสของคุณA
:
B b = new B();
b.ts();
โอเคยอมรับว่าสร้างขึ้นอย่างใด แต่อาจสมเหตุสมผลสำหรับบางกรณี
คุณไม่ควรเรียกใช้วิธีการแบบคงที่ในอินสแตนซ์ แต่ใช้กับคลาสโดยตรงคุณจะไม่มีปัญหานั้น ตัวอย่างเช่น IntelliJ IDEA จะแสดงคำเตือนหากคุณเรียกใช้วิธีการแบบคงที่บนอินสแตนซ์และเช่นกันหากคุณทำวิธีคงที่เป็นขั้นสุดท้าย