Notes & software courses · Free to learn
Aph's Blog
On this page

Inheritance vs Composition

👋 อ่านฟรีทั้งหมดบน Aph's Blog — เนื้อหาภาษาไทย ทำตามทีละหน้าใน sidebar ได้เลย หากมีข้อเสนอแนะหรืออยากให้เพิ่มหัวข้อไหน บอกได้เสมอ

ความสัมพันธ์ "เป็น" (is-a) กับ "มี" (has-a) และเมื่อไหร่ควรเลือกแบบไหน

เมื่อออกแบบ class เรามักเชื่อมโยง class เข้าด้วยกัน 2 แบบหลัก: inheritance (สืบทอด — ความสัมพันธ์ "เป็น") และ composition (ประกอบ — ความสัมพันธ์ "มี") เลือกถูกทำให้โค้ดยืดหยุ่นและดูแลง่าย

Inheritance = ความสัมพันธ์ "เป็น" (is-a)

ใช้เมื่อสิ่งหนึ่ง "เป็นชนิดหนึ่งของ" อีกสิ่ง เช่น แมว เป็น สัตว์, รถยนต์ เป็น ยานพาหนะ ถ้าพูดว่า "A เป็น B" แล้วฟังขึ้น ก็เหมาะกับ inheritance

python
class Vehicle:
    def __init__(self, brand):
        self.brand = brand
    def move(self):
        return f"{self.brand} กำลังเคลื่อนที่"

class Car(Vehicle):      # Car "เป็น" Vehicle
    def honk(self):
        return "ปี๊น ปี๊น"

c = Car("Toyota")
print(c.move())  # Toyota กำลังเคลื่อนที่
print(c.honk())  # ปี๊น ปี๊น

Composition = ความสัมพันธ์ "มี" (has-a)

ใช้เมื่อสิ่งหนึ่ง "มี" อีกสิ่งเป็นส่วนประกอบ เช่น รถยนต์ มี เครื่องยนต์, คอมพิวเตอร์ มี ซีพียู เราให้ object หนึ่งถือ object อื่นไว้เป็น attribute

python
class Engine:
    def start(self):
        return "ติดเครื่อง"

class Car:
    def __init__(self, brand):
        self.brand = brand
        self.engine = Engine()    # Car "มี" Engine
    def drive(self):
        return f"{self.brand}: {self.engine.start()} แล้วออกตัว"

print(Car("Honda").drive())  # Honda: ติดเครื่อง แล้วออกตัว

เลือกแบบไหนดี

หลักง่าย ๆ ที่นิยมกันคือ "prefer composition over inheritance" (เลือกประกอบมากกว่าสืบทอดเมื่อทำได้) เพราะ composition ยืดหยุ่นกว่าและลดการผูกมัดที่แน่นเกินไป

Inheritance (is-a)Composition (has-a)
ความสัมพันธ์A เป็นชนิดของ BA มี B เป็นส่วนประกอบ
ตัวอย่างแมว เป็น สัตว์รถ มี เครื่องยนต์
ความยืดหยุ่นน้อยกว่า (ผูกแน่น)มากกว่า (สลับชิ้นส่วนได้)
เมื่อไหร่ใช้is-a ฟังขึ้นจริง ๆส่วนใหญ่ใช้อันนี้ได้
กับดักของ inheritance ที่ลึกเกินไป

การสืบทอดหลายชั้น (A → B → C → D) ทำให้ตามโค้ดยาก แก้ class แม่ทีกระทบลูกหลานทั้งหมด ถ้าไม่ใช่ is-a จริง ๆ ให้ใช้ composition แทน จะแยกส่วนชัดและทดสอบง่ายกว่า

สรุปหัวข้อนี้

  • Inheritance = ความสัมพันธ์ "เป็น" (is-a) เช่น Car เป็น Vehicle
  • Composition = ความสัมพันธ์ "มี" (has-a) เช่น Car มี Engine
  • เลือก inheritance เมื่อ is-a ฟังขึ้นจริง ๆ นอกนั้นมักใช้ composition
  • หลักนิยม: prefer composition over inheritance — ยืดหยุ่นและดูแลง่ายกว่า
แบบฝึกหัด

1) ออกแบบ class Computer ที่ "มี" CPU และ RAM (composition) 2) ออกแบบ Shape แม่ แล้ว Circle/Square สืบทอด (inheritance) 3) ตัดสินใจ: Library กับ Book ควรเป็น is-a หรือ has-a? 4) ลองเขียน Playlist ที่ "มี" ลิสต์ของ Song