
“สวัสดี อามีโก้!”
"สวัสดี บิลาโบ!"
"วันนี้ฉันจะบอกคุณเกี่ยวกับคำหลักหลายคำใน Java แต่ฉันจะเริ่มด้วยคำที่น่าสนใจที่สุด: คำหลักสุดท้าย "
"คุณสามารถใช้คำหลักสุดท้ายเมื่อประกาศตัวแปร เมธอด หรือคลาส"
"แล้วทำไมเราถึงต้องการขั้นสุดท้าย"
"มันง่ายมาก ถ้าเราทำเครื่องหมายตัวแปรเป็นขั้นสุดท้าย ตัวแปรนั้นจะไม่เปลี่ยนแปลง:"
final int i = 5;
i++; //Compilation error: the value of i cannot be changed.
"ฉันเห็น."
"หากเราทำเครื่องหมายเมธอดเป็นขั้นสุดท้าย การแทนที่เมธอดในคลาสที่ได้รับมานั้นเป็นสิ่งต้องห้าม:"
class Cat
{
public final String getName()
{
return "cat";
}
}
class Tiger extends Cat
{
public String getName() //Compilation error: overriding the getName()
{
return "tiger";
}
}
“เข้าใจแล้ว แต่ทำไมคุณต้องห้ามการเอาชนะเมธอดด้วยล่ะ”
"ตัวอย่าง สมมติว่าโปรแกรมเมอร์เขียนโค้ดสำคัญจำนวนมากในเมธอดหนึ่งๆ และต้องการรับประกันว่าคลาสทั้งหมดที่สืบทอดคลาสของเขาจะมีพฤติกรรมตามที่ระบุ"
"และสุดท้าย การใช้งานครั้งที่สาม"
"หากเรากำหนดคลาสด้วยคีย์เวิร์ดสุดท้าย คลาสนั้นจะไม่สามารถสืบทอดได้"
public final class Cat
{
public String getName()
{
return "cat";
}
}
class Tiger extends Cat //Compilation error: the Cat class cannot be
{
public String getName()
{
return "tiger";
}
}
"แล้วทำไมเราถึงห้ามไม่ให้สืบทอดคลาสล่ะ"
"คุณควรเข้าใจว่าเราไม่ได้ป้องกันไม่ให้การสืบทอดเป็นสิ่งที่น่ารำคาญ แต่เพื่อความปลอดภัยและความสมบูรณ์ของโค้ด หากไม่มีการห้ามการสืบทอดคลาส ความหมายก็คืออนุญาต และโค้ดที่เขียนโดยคลาส ผู้ออกแบบจะทำงานอย่างถูกต้องสำหรับออบเจกต์ของคลาสนี้ เช่นเดียวกับอ็อบเจ็กต์ของคลาสที่ได้รับมา"
"แต่หากนักพัฒนาตระหนักว่าแม้การเปลี่ยนแปลงเล็กน้อยในคลาสของเขาจะทำให้ทุกอย่างหยุดทำงานตามที่คาดไว้ ก็เป็นการดีกว่าที่จะห้ามการสืบทอด"
"ตัวอย่างเช่น คลาสสตริงถูกประกาศเป็นขั้นสุดท้าย เช่นเดียวกับประเภทดั้งเดิมทั้งหมด: จำนวนเต็ม บูลีน ดับเบิ้ล อักขระ…"
"อ่า เข้าใจแล้ว คลาสสตริงถูกสร้างขึ้นให้เป็นคลาสที่ไม่เปลี่ยนรูป และถ้าพวกมันเปลี่ยนรูปกะทันหัน หลายๆ อย่างก็จะหยุดทำงาน"
"เกือบแล้ว สมมุติว่าทุกอย่างทำงานได้เกือบเหมือนเดิม แต่บางครั้งก็มีข้อผิดพลาดที่ยากต่อการค้นหาและเข้าใจ ดังนั้น ในบางกรณี การสืบทอดคลาสหรือเมธอดก็ไม่ถือเป็นบาป แต่การห้ามหมายความว่าข้อผิดพลาดน้อยลงที่จะจับได้ในภายหลัง"
"คุณสามารถใช้ไฟนอลได้ที่ไหนอีก"
"คุณสามารถใช้คำสุดท้ายก่อนพารามิเตอร์ของฟังก์ชัน และก่อนตัวแปรในเมธอดได้ นี่คือตัวอย่าง:"
public void setName(final String name)
{
final String displayName = "Mr."+ name;
…
this.name = displayName;
}
"แล้วประเด็นนั้นคืออะไร"
"มีสองอย่าง อย่างแรก เราประกาศตัวแปรเป็นขั้นสุดท้าย ถ้าเราต้องการบอกนักพัฒนาคนอื่นๆ ว่าค่านี้เป็นค่าคงที่เฉพาะ ไม่ใช่แค่ตัวแปร"
ตัวอย่างเช่น เราต้องการคำนวณภาษีขายตามราคา:
public int getPriceNDS()
{
final int NDS = 20;
return this.price * NDS / 200;
}
"และประการที่สอง เราต้องการตัวแปรประเภทนี้เมื่อเขียนคลาสภายในแบบโลคัลหรือไม่ระบุตัวตน ฉันจะบอกคุณเกี่ยวกับคลาสประเภทนี้เร็วๆ นี้ แต่ไม่ใช่วันนี้"
“โอเค จนถึงตอนนี้ยังไม่มีอะไรซับซ้อนเกินไป”
"โปรดทราบว่าเฉพาะตัวแปรเท่านั้นที่ไม่สามารถเปลี่ยนแปลงได้ ไม่ใช่วัตถุที่อาจอ้างถึง วัตถุยังคงสามารถเปลี่ยนแปลงได้"
“ที่จริงฉันแค่จะถามเรื่องนั้น และไม่มีทางที่จะทำให้วัตถุนั้นไม่เปลี่ยนแปลง?”
"ไม่ เว้นแต่คุณจะเขียนคลาสที่ไม่เปลี่ยนรูป"
"โปรดทราบว่าเนื่องจากค่าของตัวแปรสุดท้ายไม่สามารถเปลี่ยนแปลงได้ คุณต้องกำหนดค่าเริ่มต้นทันที"
รหัสนี้จะรวบรวม | รหัสนี้จะไม่รวบรวม |
---|---|
|
|
"แต่อย่างที่บอกว่า Java ให้คุณชะลอการเริ่มต้นของตัวแปรสุดท้ายของคลาสได้จนกว่าตัวสร้าง"
รหัสนี้จะรวบรวม | รหัสนี้จะไม่รวบรวม |
---|---|
|
|
"นอกจากนี้ ตัวสร้างที่แตกต่างกันสามารถเริ่มต้นตัวแปรสุดท้ายด้วยค่าที่แตกต่างกัน ซึ่งค่อนข้างสะดวก:"
class Home
{
private final int width;
private final int height;
public Home()
{
height = 100;
width = 200;
}
public Home(int width)
{
this.height = 300;
this.width = width;
}
public Home(int width, int height)
{
this.height = height;
this.width = width;
}
}
"นั่นเป็นหัวข้อที่น่าสนใจจริงๆ และทุกอย่างสมเหตุสมผล ขอบคุณ Bilaabo!"
GO TO FULL VERSION