บทที่ 4.2: การสืบทอดและการพหุรูปร่าง (Inheritance & Polymorphism)
เอกสารนี้อธิบายเกี่ยวกับแนวคิดการสืบทอดคุณสมบัติ (Inheritance) การเรียกใช้งานเมธอดของคลาสแม่ด้วย super() การสืบทอดหลายทาง (Multiple Inheritance) ลำดับ MRO การทำ Method Overriding พหุรูปร่าง (Polymorphism) และการสร้าง Abstract Class
1. การสืบทอดคุณสมบัติ (Inheritance)
การสืบทอดช่วยให้คลาสลูก (Child Class / Subclass) สามารถรับคุณสมบัติ (Attributes) และเมธอด (Methods) จากคลาสแม่ (Parent Class / Superclass) มาใช้งานได้ โดยไม่ต้องเขียนโค้ดซ้ำซ้อน
1.1 ไวยากรณ์และการใช้ฟังก์ชัน super()
ฟังก์ชัน super() ใช้สำหรับอ้างอิงและเรียกใช้งานเมธอดหรือ Constructor ของคลาสแม่
# Parent Class
class Animal:
def __init__(self, name):
self.name = name
def make_sound(self):
return "บางเสียง..."
# Child Class
class Dog(Animal):
def __init__(self, name, breed):
# เรียกใช้งาน Constructor ของคลาสแม่เพื่อกำหนดค่า self.name
super().__init__(name)
self.breed = breed
# Method Overriding (เขียนทับการทำงานของคลาสแม่)
def make_sound(self):
return "โฮ่งๆ!"
dog = Dog("มอมแมม", "โกลเด้น")
print(dog.name) # Output: มอมแมม (ได้รับจากคลาสแม่)
print(dog.make_sound()) # Output: โฮ่งๆ! (ทำงานตามเมธอดของคลาสลูก)
2. การสืบทอดหลายทางและ MRO (Multiple Inheritance & MRO)
Python รองรับการสืบทอดจากหลายคลาสแม่พร้อมกัน (Multiple Inheritance) โดยมีลำดับการค้นหาเมธอดเรียกว่า Method Resolution Order (MRO)
class A:
def show(self):
print("ทำงานที่ A")
class B(A):
def show(self):
print("ทำงานที่ B")
class C(A):
def show(self):
print("ทำงานที่ C")
class D(B, C):
pass
d = D()
d.show() # Output: ทำงานที่ B
# ตรวจสอบลำดับ MRO
print([cls.__name__ for cls in D.mro()])
# Output: ['D', 'B', 'C', 'A', 'object']
3. พหุรูปร่าง (Polymorphism)
Polymorphism คือความสามารถในการจัดการกับ Object ต่างคลาสกันผ่าน Interface เดียวกัน โดยแต่ละ Object จะตอบสนองต่อการเรียกใช้เมธอดในรูปแบบของตนเอง
class Circle:
def __init__(self, radius):
self.radius = radius
def calculate_area(self):
return 3.14159 * (self.radius ** 2)
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
def calculate_area(self):
return self.width * self.height
# ฟังก์ชันที่รับ Object รูปทรงใดก็ได้มาคำนวณพื้นที่
def print_area(shape):
# เรียกใช้ calculate_area() โดยไม่ต้องกังวลว่าเป็น Class ไหน
print(f"พื้นที่: {shape.calculate_area():,.2f}")
shapes = [Circle(5), Rectangle(4, 6)]
for shape in shapes:
print_area(shape)
# Output:
# พื้นที่: 78.54
# พื้นที่: 24.00
4. คลาส 추상และเมธอด추상 (Abstract Base Classes - ABC)
Abstract Base Class คือคลาสแม่แบบที่ไม่สามารถนำไปสร้าง Instance ได้โดยตรง ใช้สำหรับบังคับให้คลาสลูกที่สืบทอดไป ต้องเขียนเมธอดตามที่กำหนดไว้เสมอ ผ่านโมดูล abc
from abc import ABC, abstractmethod
# คลาสแม่แบบ Abstract Class
class PaymentProcessor(ABC):
@abstractmethod
def process_payment(self, amount):
"""บังคับให้คลาสลูกต้อง implement เมธอดนี้"""
pass
class CreditCardPayment(PaymentProcessor):
def process_payment(self, amount):
print(f"ชำระเงินด้วยบัตรเครดิตจำนวน {amount:,.2f} บาท สำเร็จ")
class PayPalPayment(PaymentProcessor):
def process_payment(self, amount):
print(f"ชำระเงินผ่าน PayPal จำนวน {amount:,.2f} บาท สำเร็จ")
# payment = PaymentProcessor() # จะเกิด TypeError ทันที เนื่องจากเป็น Abstract Class
cc = CreditCardPayment()
cc.process_payment(1500) # Output: ชำระเงินด้วยบัตรเครดิตจำนวน 1,500.00 บาท สำเร็จ