1. บทนำ
Java เป็นภาษาการเขียนโปรแกรมที่ถูกนำไปใช้อย่างแพร่หลายในหลากหลายสาขา ตั้งแต่ระบบองค์กรไปจนถึงแอปพลิเคชันเว็บและการพัฒนา Android จากคุณสมบัติมากมายของมัน “inheritance” เป็นหนึ่งในแนวคิดที่สำคัญที่สุดเมื่อเรียนรู้การเขียนโปรแกรมเชิงวัตถุ
โดยการใช้ inheritance คลาสใหม่ (subclass/child class) สามารถรับช่วงต่อฟังก์ชันการทำงานของคลาสที่มีอยู่ (superclass/parent class) ซึ่งช่วยลดการทำซ้ำของโค้ดและทำให้โปรแกรมง่ายต่อการขยายและบำรุงรักษา ใน Java inheritance ถูกนำไปใช้งานโดยใช้คำสำคัญ extends ในบทความนี้ เราจะอธิบายอย่างชัดเจนถึงบทบาทของคำสำคัญ extends ใน Java การใช้งานพื้นฐาน การประยุกต์ใช้จริง และคำถามทั่วไป คู่มือนี้มีประโยชน์ไม่เพียงแต่สำหรับผู้เริ่มต้นใน Java แต่ยังสำหรับผู้ที่ต้องการทบทวน inheritance ด้วย พอถึงตอนจบ คุณจะเข้าใจข้อดีและข้อเสียของ inheritance รวมถึงข้อพิจารณาการออกแบบที่สำคัญอย่างครบถ้วน
มาเริ่มต้นด้วยการดูใกล้ชิดมากขึ้นกับ “inheritance ใน Java คืออะไร?”
2. Inheritance ใน Java คืออะไร?
Inheritance ใน Java เป็นกลไกที่คลาสหนึ่ง (superclass/parent class) ส่งผ่านลักษณะและฟังก์ชันการทำงานของมันไปยังคลาสอื่น (subclass/child class) ด้วย inheritance ฟิลด์ (ตัวแปร) และเมธอด (ฟังก์ชัน) ที่กำหนดใน parent class สามารถนำกลับมาใช้ใน child class ได้ กลไกนี้ทำให้ง่ายต่อการจัดระเบียบและจัดการโค้ด รวมถึงการรวมกระบวนการที่ใช้ร่วมกัน และการขยายหรือปรับเปลี่ยนฟังก์ชันการทำงานอย่างยืดหยุ่น Inheritance เป็นหนึ่งในสามเสาหลักของการเขียนโปรแกรมเชิงวัตถุ (OOP) ร่วมกับ encapsulation และ polymorphism
เกี่ยวกับความสัมพันธ์แบบ “is-a”
ตัวอย่างทั่วไปของ inheritance คือ “ความสัมพันธ์แบบ is-a” เช่น “Dog is an Animal” ซึ่งหมายความว่า Dog class สืบทอดจาก Animal class Dog สามารถรับลักษณะและพฤติกรรมของ Animal ในขณะที่เพิ่มคุณสมบัติเฉพาะตัวของตัวเอง
class Animal {
void eat() {
System.out.println("食べる");
}
}
class Dog extends Animal {
void bark() {
System.out.println("ワンワン");
}
}
ในตัวอย่างนี้ Dog class สืบทอดจาก Animal class ตัวอย่างของ Dog สามารถใช้ทั้งเมธอด bark และเมธอด eat ที่สืบทอดมา
เกิดอะไรขึ้นเมื่อใช้ Inheritance?
- คุณสามารถรวมตรรกะและข้อมูลที่ใช้ร่วมกันไว้ใน parent class ลดความจำเป็นในการเขียนโค้ดซ้ำๆ ในแต่ละ subclass
- แต่ละ subclass สามารถเพิ่มพฤติกรรมเฉพาะตัวของตัวเองหรือ override เมธอดของ parent class
การใช้ inheritance ช่วยจัดโครงสร้างโปรแกรมและทำให้การเพิ่มคุณสมบัติและการบำรุงรักษาง่ายขึ้น อย่างไรก็ตาม inheritance ไม่ใช่ตัวเลือกที่ดีที่สุดเสมอไป และสำคัญที่จะประเมินอย่างรอบคอบว่ามีความสัมพันธ์แบบ “is-a” จริงๆ ระหว่างการออกแบบหรือไม่
3. คำสำคัญ extends ทำงานอย่างไร
คำสำคัญ extends ใน Java ประกาศการสืบทอดของคลาสอย่างชัดเจน เมื่อ child class สืบทอดฟังก์ชันการทำงานของ parent class จะใช้ไวยากรณ์ extends ParentClassName ในประกาศคลาส ซึ่งทำให้ child class สามารถใช้สมาชิกสาธารณะทั้งหมด (ฟิลด์และเมธอด) ของ parent class ได้โดยตรง
ไวยากรณ์พื้นฐาน
class ParentClass {
// Fields and methods of the parent class
}
class ChildClass extends ParentClass {
// Fields and methods unique to the child class
}
ตัวอย่างเช่น โดยใช้ Animal และ Dog class จากก่อนหน้า เราจะได้:
class Animal {
void eat() {
System.out.println("食べる");
}
}
class Dog extends Animal {
void bark() {
System.out.println("ワンワン");
}
}
โดยการเขียน Dog extends Animal คลาส Dog จะสืบทอดจาก Animal class และสามารถใช้เมธอด eat ได้
การใช้สมาชิกของ Parent Class
ด้วย inheritance ตัวอย่างของ child class สามารถเข้าถึงเมธอดและฟิลด์ของ parent class (ตราบใดที่ตัวปรับสิทธิ์การเข้าถึงอนุญาต):
Dog dog = new Dog();
dog.eat(); // Calls the parent class method
dog.bark(); // Calls the child class method
ข้อควรทราบสำคัญ
- Java อนุญาตให้สืบทอดจากคลาสได้เพียงคลาสเดียว (single inheritance) คุณไม่สามารถระบุหลายคลาสหลัง
extendsได้ - หากต้องการป้องกันการสืบทอด คุณสามารถใช้ตัวแก้ไข
finalกับคลาสได้
เคล็ดลับการพัฒนาปฏิบัติ
การใช้ extends อย่างถูกต้องช่วยให้คุณรวมฟังก์ชันการทำงานทั่วไปไว้ในคลาสพาเรนต์และขยายหรือปรับแต่งพฤติกรรมในซับคลาส นอกจากนี้ยังเป็นประโยชน์เมื่อคุณต้องการเพิ่มฟีเจอร์ใหม่โดยไม่ต้องแก้ไขโค้ดที่มีอยู่
4. การโอเวอร์ไรด์เมธอดและคีย์เวิร์ด super
เมื่อใช้การสืบทอด มีกรณีที่คุณต้องการเปลี่ยนพฤติกรรมของเมธอดที่กำหนดไว้ในคลาสพาเรนต์ ซึ่งเรียกว่า “การโอเวอร์ไรด์เมธอด” ใน Java การโอเวอร์ไรด์ทำได้โดยการกำหนดเมธอดในคลาสลูกที่มีชื่อและรายการพารามิเตอร์เดียวกับเมธอดในคลาสพาเรนต์
การโอเวอร์ไรด์เมธอด
เมื่อทำการโอเวอร์ไรด์เมธอด มักจะเพิ่มแอนโนเทชัน @Override ซึ่งช่วยให้คอมไพเลอร์ตรวจจับข้อผิดพลาดโดยไม่ได้ตั้งใจ เช่น ชื่อเมธอดหรือสิกเนเจอร์ที่ไม่ถูกต้อง
class Animal {
void eat() {
System.out.println("食べる");
}
}
class Dog extends Animal {
@Override
void eat() {
System.out.println("ドッグフードを食べる");
}
}
ในตัวอย่างนี้ คลาส Dog โอเวอร์ไรด์เมธอด eat เมื่อเรียก eat บนอินสแตนซ์ของ Dog ผลลัพธ์จะเป็น “ドッグフードを食べる”
Dog dog = new Dog();
dog.eat(); // Displays: ドッグフードを食べる
การใช้คีย์เวิร์ด super
หากต้องการเรียกเมธอดดั้งเดิมของคลาสพาเรนต์ภายในเมธอดที่โอเวอร์ไรด์ ให้ใช้คีย์เวิร์ด super
class Dog extends Animal {
@Override
void eat() {
super.eat(); // Calls the parent class’s eat()
System.out.println("ドッグフードも食べる");
}
}
โค้ดนี้จะเรียกเมธอด eat ของคลาสพาเรนต์ก่อน แล้วจึงเพิ่มพฤติกรรมของซับคลาสต่อไป
คอนสตรัคเตอร์และ super
หากคลาสพาเรนต์มีคอนสตรัคเตอร์ที่รับพารามิเตอร์ คลาสลูกต้องเรียกคอนสตรัคเตอร์นั้นโดยใช้ super(arguments) เป็นบรรทัดแรกของคอนสตรัคเตอร์ของตนเอง
class Animal {
Animal(String name) {
System.out.println("Animal: " + name);
}
}
class Dog extends Animal {
Dog(String name) {
super(name);
System.out.println("Dog: " + name);
}
}
สรุป
- การโอเวอร์ไรด์หมายถึงการกำหนดเมธอดของคลาสพาเรนต์ใหม่ในคลาสลูก
- แนะนำให้ใช้แอนโนเทชัน
@Override - ใช้
superเมื่อคุณต้องการใช้การทำงานของเมธอดในคลาสพาเรนต์ซ้ำ superยังใช้เมื่อต้องเรียกคอนสตรัคเตอร์ของคลาสพาเรนต์
5. ข้อดีและข้อเสียของการสืบทอด
การใช้การสืบทอดใน Java นำมาซึ่งประโยชน์หลายประการต่อการออกแบบและการพัฒนาโปรแกรม อย่างไรก็ตาม การใช้ไม่ถูกต้องอาจทำให้เกิดปัญหาที่รุนแรง ด้านล่างนี้เราจะอธิบายข้อดีและข้อเสียอย่างละเอียด
ข้อดีของการสืบทอด
- เพิ่มการนำโค้ดกลับมาใช้ใหม่ การกำหนดตรรกะและข้อมูลที่ใช้ร่วมกันในคลาสพาเรนต์ช่วยขจัดความจำเป็นในการทำซ้ำโค้ดเดียวกันในแต่ละซับคลาส ลดการทำซ้ำและเพิ่มความสามารถในการบำรุงรักษาและอ่านโค้ด
- ขยายได้ง่าย เมื่อจำเป็นต้องเพิ่มฟังก์ชันใหม่ คุณสามารถสร้างซับคลาสใหม่จากคลาสพาเรนต์โดยไม่ต้องแก้ไขโค้ดที่มีอยู่ ซึ่งช่วยลดผลกระทบจากการเปลี่ยนแปลงและลดโอกาสเกิดบั๊ก
- สนับสนุนพอลีมอร์ฟิซึม การสืบทอดทำให้ “ตัวแปรของคลาสพาเรนต์สามารถอ้างอิงถึงอินสแตนซ์ของคลาสลูก” ซึ่งช่วยให้การออกแบบที่ยืดหยุ่นโดยใช้อินเทอร์เฟซทั่วไปและพฤติกรรมพอลีมอร์ฟิก
ข้อเสียของการสืบทอด
- (ส่วนนี้ยังไม่ได้แปลต่อในข้อความต้น)
- โครงสร้างลำดับชั้นลึกทำให้การออกแบบซับซ้อน หากสายการสืบทอดเติบโตลึกเกินไป จะทำให้ยากต่อการเข้าใจว่าพฤติกรรมถูกกำหนดที่ไหน ทำให้การบำรุงรักษายากขึ้น
- การเปลี่ยนแปลงในคลาสพาเรนท์ส่งผลต่อทุกซับคลาส การแก้ไขพฤติกรรมของคลาสพาเรนท์อาจทำให้เกิดปัญหาโดยไม่ตั้งใจในทุกซับคลาส คลาสพาเรนท์ต้องการการออกแบบและการอัปเดตอย่างระมัดระวัง
- อาจลดความยืดหยุ่นของการออกแบบ การใช้การสืบทอดมากเกินไปทำให้คลาสเชื่อมโยงกันอย่างแน่นหนา ทำให้การเปลี่ยนแปลงในอนาคตทำได้ยาก ในบางกรณี ความสัมพันธ์ “has-a” ที่ใช้การประกอบ (composition) จะยืดหยุ่นกว่าการสืบทอด “is-a”
สรุป
การสืบทอดเป็นเครื่องมือที่ทรงพลัง แต่การพึ่งพามันในทุกกรณีอาจทำให้เกิดปัญหาในระยะยาว ตรวจสอบเสมอว่ามีความสัมพันธ์ “is-a” ที่แท้จริงหรือไม่ และใช้การสืบทอดเฉพาะเมื่อเหมาะสม
6. ความแตกต่างระหว่างการสืบทอดและอินเทอร์เฟซ
Java มีกลไกสำคัญสองอย่างสำหรับการขยายและจัดระเบียบฟังก์ชัน: การสืบทอดคลาส (extends) และอินเทอร์เฟซ (implements) ทั้งสองสนับสนุนการใช้โค้ดซ้ำและการออกแบบที่ยืดหยุ่น แต่โครงสร้างและการใช้งานที่ตั้งใจจะแตกต่างกันอย่างมาก ด้านล่างนี้เราจะอธิบายความแตกต่างและวิธีการเลือกใช้
ความแตกต่างระหว่าง extends และ implements
- extends (การสืบทอด)
- คุณสามารถสืบทอดจากคลาสได้เพียงคลาสเดียว (การสืบทอดแบบเดี่ยว)
- ฟิลด์และเมธอดที่ทำงานเต็มรูปแบบจากคลาสพาเรนท์สามารถใช้โดยตรงในซับคลาส
- แสดงถึงความสัมพันธ์ “is-a” (เช่น สุนัขเป็นสัตว์)
- implements (การทำงานตามอินเทอร์เฟซ)
- สามารถทำการ implement อินเทอร์เฟซหลายตัวพร้อมกันได้
- อินเทอร์เฟซมีเพียงการประกาศเมธอด (แม้ว่าจะมีเมธอด default ตั้งแต่ Java 8 เป็นต้นไป)
- แสดงถึงความสัมพันธ์ “can-do” (เช่น สุนัขสามารถเห่า, สุนัขสามารถเดิน)
ตัวอย่างการใช้อินเทอร์เฟซ
interface Walkable {
void walk();
}
interface Barkable {
void bark();
}
class Dog implements Walkable, Barkable {
public void walk() {
System.out.println("歩く");
}
public void bark() {
System.out.println("ワンワン");
}
}
ในตัวอย่างนี้ คลาส Dog ทำการ implement อินเทอร์เฟซสองตัวคือ Walkable และ Barkable เพื่อให้พฤติกรรมคล้ายกับการสืบทอดหลายคลาส 
ทำไมอินเทอร์เฟซจึงจำเป็น
Java ไม่อนุญาตให้สืบทอดหลายคลาสพร้อมกัน เนื่องจากอาจทำให้เกิดความขัดแย้งเมื่อคลาสพาเรนท์กำหนดเมธอดหรือฟิลด์เดียวกัน อินเทอร์เฟซแก้ปัญหานี้โดยให้คลาสสามารถรับหลาย “ประเภท” ได้โดยไม่ต้องสืบทอดการทำงานที่ขัดแย้งกัน
วิธีการใช้ให้ถูกต้อง
- ใช้
extendsเมื่อมีความสัมพันธ์ “is-a” ที่ชัดเจนระหว่างคลาส - ใช้
implementsเมื่อคุณต้องการกำหนดสัญญาพฤติกรรมร่วมกันให้หลายคลาส
ตัวอย่าง
- “สุนัขเป็นสัตว์” →
Dog extends Animal - “สุนัขสามารถเดินและสามารถเห่า” →
Dog implements Walkable, Barkable
สรุป
- คลาสหนึ่งสามารถสืบทอดจากคลาสพาเรนท์ได้เพียงหนึ่งคลาสเท่านั้น แต่สามารถ implement อินเทอร์เฟซหลายตัวได้
- การเลือกใช้ระหว่างการสืบทอดและอินเทอร์เฟซตามเจตนาการออกแบบจะทำให้โค้ดสะอาด ยืดหยุ่น และบำรุงรักษาได้ง่าย
7. แนวปฏิบัติที่ดีที่สุดสำหรับการใช้การสืบทอด
การสืบทอดใน Java มีพลังมาก แต่การใช้ไม่ถูกต้องอาจทำให้โปรแกรมแข็งกระด้างและบำรุงรักษายาก ด้านล่างนี้เป็นแนวปฏิบัติและแนวทางสำหรับการใช้การสืบทอดอย่างปลอดภัยและมีประสิทธิภาพ
เมื่อใดควรใช้การสืบทอด — และเมื่อใดควรหลีกเลี่ยง
- ใช้การสืบทอดเมื่อ:
- มีความสัมพันธ์ “is-a” ที่ชัดเจน (เช่น สุนัขเป็นสัตว์)
- ต้องการใช้ฟังก์ชันของคลาสพาเรนท์และขยายต่อ
- ต้องการกำจัดโค้ดซ้ำซ้อนและรวมตรรกะที่ใช้ร่วมกันไว้ในที่เดียว
- หลีกเลี่ยงการสืบทอดเมื่อ:
- คุณใช้มันเพียงเพื่อการใช้ซ้ำของโค้ด (ซึ่งมักทำให้การออกแบบคลาสไม่เป็นธรรมชาติ)
- ความสัมพันธ์ “has-a” เหมาะสมกว่า — ในกรณีนี้ควรพิจารณาการประกอบ (composition)
การเลือกใช้ระหว่างการสืบทอดและการประกอบ
- การสืบทอด (
extends): ความสัมพันธ์แบบ is-a - ตัวอย่าง:
Dog extends Animal - มีประโยชน์เมื่อคลาสย่อยแท้จริงเป็นประเภทของคลาสพาเรนต์
- การรวม (Composition) (ความสัมพันธ์แบบ has-a)
- ตัวอย่าง: รถยนต์ (Car) มีเครื่องยนต์ (Engine)
- ใช้ตัวอย่างของคลาสอื่นภายในเพื่อเพิ่มฟังก์ชันการทำงาน
- ยืดหยุ่นมากกว่าและปรับเปลี่ยนได้ง่ายต่อการเปลี่ยนแปลงในอนาคต
แนวทางการออกแบบเพื่อป้องกันการใช้การสืบทอดอย่างไม่เหมาะสม
- อย่าสร้างลำดับชั้นการสืบทอดลึกเกินไป (ควรจำกัดไว้ที่ 3 ระดับหรือไม่เกิน)
- หากมีคลาสย่อยหลายคลาสสืบทอดจากพาเรนต์เดียวกัน ให้ประเมินใหม่ว่าหน้าที่ของพาเรนต์นั้นเหมาะสมหรือไม่
- พิจารณาความเสี่ยงที่การเปลี่ยนแปลงในคลาสพาเรนต์จะส่งผลต่อคลาสย่อยทั้งหมดเสมอ
- ก่อนนำการสืบทอดไปใช้ ให้พิจารณาทางเลือกอื่นเช่น อินเทอร์เฟซและการรวม (composition)
การจำกัดการสืบทอดด้วยตัวแก้ไข final
- การใส่
finalให้กับคลาสจะทำให้ไม่สามารถสืบทอดได้ - การใส่
finalให้กับเมธอดจะทำให้เมธอดนั้นไม่สามารถถูกโอเวอร์ไรด์โดยคลาสย่อยได้final class Utility { // This class cannot be inherited } class Base { final void show() { System.out.println("オーバーライド禁止"); } }
การเสริมเอกสารและคอมเมนต์
- การบันทึกความสัมพันธ์การสืบทอดและเจตนาการออกแบบคลาสใน Javadoc หรือคอมเมนต์ช่วยให้การบำรุงรักษาในอนาคตทำได้ง่ายขึ้นอย่างมาก
สรุป
การสืบทอดเป็นเครื่องมือที่สะดวก แต่ต้องใช้ด้วยความตั้งใจเสมอ ควรถามตนเองว่า “คลาสนี้เป็นประเภทของคลาสพาเรนต์จริงหรือไม่?” หากไม่แน่ใจ ให้พิจารณาการรวมหรืออินเทอร์เฟซเป็นทางเลือก
8. สรุป
จนถึงจุดนี้ เราได้อธิบายการสืบทอดใน Java และคีย์เวิร์ด extends อย่างละเอียด ตั้งแต่พื้นฐานจนถึงการใช้งานจริง ด้านล่างนี้คือสรุปประเด็นสำคัญที่กล่าวถึงในบทความนี้
- การสืบทอดใน Java ทำให้คลาสย่อยสามารถรับข้อมูลและฟังก์ชันของคลาสพาเรนต์ได้ ช่วยให้การออกแบบโปรแกรมมีประสิทธิภาพและนำกลับมาใช้ใหม่ได้
- คีย์เวิร์ด
extendsชี้แจงความสัมพันธ์ระหว่างคลาสพาเรนต์และคลาสลูก (ความสัมพันธ์แบบ “is-a”) - การโอเวอร์ไรด์เมธอดและคีย์เวิร์ด
superทำให้สามารถขยายหรือปรับแต่งพฤติกรรมที่สืบทอดมาได้ - การสืบทอดมีข้อได้เปรียบหลายอย่าง เช่น การใช้โค้ดซ้ำ การขยายตัวได้ง่าย และการสนับสนุนพอลีมอร์ฟิซึม แต่ก็มีข้อเสียเช่น ลำดับชั้นที่ลึกหรือซับซ้อนและการเปลี่ยนแปลงที่มีผลกว้าง
- การเข้าใจความแตกต่างระหว่างการสืบทอด อินเทอร์เฟซ และการรวมเป็นสิ่งสำคัญในการเลือกแนวทางการออกแบบที่เหมาะสม
- อย่าใช้การสืบทอดเกินความจำเป็น; ควรชัดเจนเกี่ยวกับเจตนาและเหตุผลของการออกแบบเสมอ
การสืบทอดเป็นหนึ่งในแนวคิดหลักของการเขียนโปรแกรมเชิงวัตถุใน Java การเข้าใจกฎและแนวปฏิบัติที่ดีที่สุดจะทำให้คุณสามารถนำไปใช้ได้อย่างมีประสิทธิภาพในงานพัฒนาจริง
9. คำถามที่พบบ่อย (FAQ)
Q1: สิ่งที่เกิดขึ้นกับคอนสตรัคเตอร์ของคลาสพาเรนต์เมื่อมีการสืบทอดคลาสใน Java คืออะไร?
A1: หากคลาสพาเรนต์มีคอนสตรัคเตอร์ที่ไม่มีอาร์กิวเมนต์ (ค่าเริ่มต้น) จะถูกเรียกโดยอัตโนมัติจากคอนสตรัคเตอร์ของคลาสลูก หากคลาสพาเรนต์มีคอนสตรัคเตอร์ที่รับพารามิเตอร์เท่านั้น คลาสลูกจะต้องเรียกมันอย่างชัดเจนโดยใช้ super(arguments) ที่จุดเริ่มต้นของคอนสตรัคเตอร์ของมัน
Q2: Java สามารถทำการสืบทอดหลายคลาสได้หรือไม่?
A2: ไม่ได้ Java ไม่รองรับการสืบทอดหลายคลาส คลาสสามารถ extends พาเรนต์คลาสได้เพียงคลาสเดียวเท่านั้น อย่างไรก็ตามคลาสสามารถ implements อินเทอร์เฟซหลายตัวได้
Q3: ความแตกต่างระหว่างการสืบทอดและการคอมโพสชันคืออะไร?
A3: การสืบทอดแสดงความสัมพันธ์ “เป็น‑a” (is‑a) ซึ่งคลาสลูกใช้ฟังก์ชันและข้อมูลของคลาสพาเรนต์ ส่วนการคอมโพสชันแสดงความสัมพันธ์ “มี‑a” (has‑a) ซึ่งคลาสหนึ่งมีอ็อบเจกต์ของคลาสอื่น การคอมโพสชันมักให้ความยืดหยุ่นมากกว่าและมักเป็นทางเลือกที่ดีกว่าในหลายกรณีที่ต้องการการแยกส่วนอย่างอิสระหรือการขยายในอนาคต
Q4: ตัวแก้ไข final จำกัดการสืบทอดและการโอเวอร์ไรด์หรือไม่?
A4: ใช่ หากคลาสถูกทำเครื่องหมายว่า final จะไม่สามารถสืบทอดได้ หากเมธอดถูกทำเครื่องหมายว่า final จะไม่สามารถโอเวอร์ไรด์ในซับคลาสได้ สิ่งนี้มีประโยชน์เพื่อรับประกันพฤติกรรมที่สอดคล้องหรือเพื่อเหตุผลด้านความปลอดภัย
Q5: จะเกิดอะไรขึ้นหากคลาสพาเรนต์และคลาสลูกกำหนดฟิลด์หรือเมธอดที่มีชื่อเดียวกัน?
A5: หากฟิลด์ที่มีชื่อเดียวกันถูกกำหนดในทั้งสองคลาส ฟิลด์ในคลาสลูกจะซ่อนฟิลด์ของพาเรนต์ (shadowing) ส่วนเมธอดจะแตกต่างกัน: หากลายเซ็นตรงกัน เมธอดของคลาสลูกจะโอเวอร์ไรด์เมธอดของพาเรนต์ โปรดทราบว่าฟิลด์ไม่สามารถโอเวอร์ไรด์ได้—สามารถซ่อนเท่านั้น
Q6: จะเกิดอะไรขึ้นหากความลึกของการสืบทอดมากเกินไป?
A6: โครงสร้างการสืบทอดที่ลึกทำให้โค้ดอ่านและบำรุงรักษายากขึ้น การตามหาตำแหน่งที่ตรรกะถูกกำหนดกลายเป็นเรื่องยาก สำหรับการออกแบบที่ดูแลได้ ควรพยายามให้ความลึกของการสืบทอดตื้นและแยกบทบาทให้ชัดเจน
Q7: ความแตกต่างระหว่างการโอเวอร์ไรด์และการโอเวอร์โหลดคืออะไร?
A7: การโอเวอร์ไรด์คือการกำหนดเมธอดใหม่จากคลาสพาเรนต์ในคลาสลูก ส่วนการโอเวอร์โหลดคือการกำหนดเมธอดหลายตัวในคลาสเดียวกันโดยใช้ชื่อเดียวกันแต่พารามิเตอร์ต่างกัน (ประเภทหรือจำนวน)
Q8: ควรใช้คลาสแอ็บสแตรกต์และอินเทอร์เฟซอย่างไรให้แตกต่างกัน?
A8: คลาสแอ็บสแตรกต์ใช้เมื่อคุณต้องการให้มีการนำเสนอการทำงานหรือฟิลด์ที่ใช้ร่วมกันระหว่างคลาสที่เกี่ยวข้อง อินเทอร์เฟซใช้เมื่อคุณต้องการกำหนดสัญญาพฤติกรรมที่หลายคลาสสามารถนำไปใช้ได้ ใช้คลาสแอ็บสแตรกต์สำหรับโค้ดที่ใช้ร่วมกันและใช้อินเทอร์เฟซเมื่อคุณต้องการแสดงหลายประเภทหรือความสามารถหลายอย่างพร้อมกัน
