คลาสนามธรรมใน Python

คลาสนามธรรมใน Python

บทความนี้อธิบายเกี่ยวกับคลาสนามธรรมใน Python

เราจะอธิบายกลไกพื้นฐานของคลาสนามธรรมโดยใช้โมดูล abc พร้อมตัวอย่างที่นำไปใช้ได้จริงและคำอธิบายพร้อมโค้ด

YouTube Video

คลาสนามธรรมใน Python

โมดูล abc ของ Python (Abstract Base Classes) เป็นส่วนหนึ่งของไลบรารีมาตรฐานและใช้สำหรับกำหนดคลาสนามธรรม ซึ่งให้เป็นแม่แบบของเมธอดที่คลาสต้องกำหนด การใช้โมดูลนี้เพิ่มความยืดหยุ่นและความทนทานในงานออกแบบคลาส

คลาสนามธรรมคืออะไร?

คลาสนามธรรมคือคลาสที่ใช้กำหนดอินเตอร์เฟซร่วมกันสำหรับคลาสที่เป็นรูปธรรม (instantiable) คลาสนามธรรมไม่สามารถสร้างอินสแตนซ์เองได้ ต้องมีการกำหนดการใช้งานจริงในคลาสอนุพันธ์ (subclass)

โมดูล abc อนุญาตให้คุณกำหนดเมธอดหรือลักษณะเฉพาะแบบนามธรรม และบังคับให้มีการใช้งานในคลาสที่สืบทอด หากมีเมธอดนามธรรมแม้แต่หนึ่งรายการที่ไม่ได้ถูกใช้งาน คลาสนั้นจะไม่สามารถสร้างอินสแตนซ์ได้

วิธีการใช้โมดูล abc

ในการสร้างคลาสนามธรรมโดยใช้โมดูล abc คุณต้องสืบทอดจากคลาส ABC และกำหนดเมธอดนามธรรมโดยใช้ตัวตกแต่ง @abstractmethod

 1from abc import ABC, abstractmethod
 2
 3# Definition of the abstract base class
 4class Animal(ABC):
 5
 6    @abstractmethod
 7    def sound(self):
 8        pass
 9
10# Concrete implementation in the subclass
11class Dog(Animal):
12    def sound(self):
13        return "Woof!"
14
15class Cat(Animal):
16    def sound(self):
17        return "Meow!"

ที่นี่ คลาส Animal ถูกกำหนดเป็นคลาสนามธรรมและมีเมธอดนามธรรมที่ชื่อว่า sound เมธอดนี้จะต้องถูกใช้งานจริงในคลาสอนุพันธ์ (subclasses) Dog และ Cat สืบทอดจาก Animal และแต่ละตัวได้ใช้งานเมธอด sound

การสร้างอินสแตนซ์จากคลาสนามธรรม

คลาสนามธรรมไม่สามารถสร้างอินสแตนซ์โดยตรงได้ ตัวอย่างเช่น การพยายามสร้างอินสแตนซ์จากคลาส Animal โดยตรงจะทำให้เกิดข้อผิดพลาด

1animal = Animal()  # TypeError: Can't instantiate abstract class Animal with abstract methods sound
  • เมื่อพยายามสร้างอินสแตนซ์จากคลาสนามธรรม Python จะระบุว่ามีเมธอดนามธรรมที่ไม่ได้ถูกใช้งาน และจะยกข้อผิดพลาด TypeError หากเมธอดนามธรรมทั้งหมดที่จำเป็นได้รับการใช้งานในคลาสอนุพันธ์ การสร้างอินสแตนซ์ก็จะเป็นไปได้

เมธอดนามธรรมหลายรายการ

เป็นไปได้เช่นกันสำหรับคลาสที่จะมีเมธอดนามธรรมหลายรายการ หากเมธอดนามธรรมทั้งหมดไม่ได้ถูกใช้งานในคลาสอนุพันธ์ คลาสนั้นก็ยังคงเป็นคลาสนามธรรมต่อไป

 1from abc import ABC, abstractmethod
 2
 3class Vehicle(ABC):
 4
 5    @abstractmethod
 6    def start_engine(self):
 7        pass
 8
 9    @abstractmethod
10    def stop_engine(self):
11        pass
12
13class Car(Vehicle):
14    def start_engine(self):
15        return "Car engine started"
16
17    def stop_engine(self):
18        return "Car engine stopped"

ในตัวอย่างนี้ คลาส Vehicle มีเมธอดเชิงนามธรรมสองตัว และคลาส Car สามารถถูกสร้างขึ้นได้เฉพาะเมื่อมีการนำเมธอดทั้งสองตัวไปใช้เท่านั้น

การกำหนดคุณสมบัติเชิงนามธรรม (Abstract Properties)

โมดูล abc สนับสนุนทั้งเมธอดเชิงนามธรรมและคุณสมบัติเชิงนามธรรม สิ่งนี้ช่วยทำให้บังคับใช้การกำหนดคุณสมบัติในคลาสที่สืบทอดได้

 1from abc import ABC, abstractmethod
 2
 3class Shape(ABC):
 4
 5    @property
 6    @abstractmethod
 7    def area(self):
 8        pass
 9
10class Circle(Shape):
11    def __init__(self, radius):
12        self.radius = radius
13
14    @property
15    def area(self):
16        return 3.14159 * (self.radius ** 2)
  • ในตัวอย่างนี้ คลาส Shape มีคุณสมบัติเชิงนามธรรม area และคลาสย่อย Circle ได้นำคุณสมบัตินี้ไปทำให้เป็นรูปธรรม ในลักษณะนี้ การใช้คลาสเชิงนามธรรมเพื่อบังคับใช้คุณสมบัติช่วยรักษาความสอดคล้องของโค้ด

การใช้ isinstance() และ issubclass()

ด้วยการใช้คลาสเชิงนามธรรม คุณสามารถยืนยันความสัมพันธ์การสืบทอดของคลาสด้วย isinstance() หรือ issubclass() ซึ่งช่วยปรับปรุงความปลอดภัยและความยืดหยุ่นของโค้ด

 1from abc import ABC, abstractmethod
 2
 3# Definition of the abstract base class
 4class Animal(ABC):
 5
 6    @abstractmethod
 7    def sound(self):
 8        pass
 9
10# Concrete implementation in the subclass
11class Dog(Animal):
12    def sound(self):
13        return "Woof!"
14
15class Cat(Animal):
16    def sound(self):
17        return "Meow!"
18
19class Vehicle(ABC):
20
21    @abstractmethod
22    def start_engine(self):
23        pass
24
25    @abstractmethod
26    def stop_engine(self):
27        pass
28
29class Car(Vehicle):
30    def start_engine(self):
31        return "Car engine started"
32
33    def stop_engine(self):
34        return "Car engine stopped"
35
36print("Dog() is an Animal? -> ", isinstance(Dog(), Animal))   # True
37print("Dog is subclass of Animal? -> ", issubclass(Dog, Animal))  # True
38print("Cat() is a Vehicle? -> ", isinstance(Cat(), Vehicle))  # False

isinstance() ถูกใช้เพื่อตรวจสอบว่าออบเจ็กต์เป็นอินสแตนซ์ของคลาสที่ระบุหรือไม่ และ issubclass() ถูกใช้เพื่อตรวจสอบว่าคลาสเป็นคลาสย่อยของคลาสที่ระบุหรือไม่

สรุป

ด้วยการออกแบบคลาสเชิงนามธรรมโดยใช้โมดูล abc คุณสามารถทำให้ส่วนเชื่อมต่อระหว่างคลาสชัดเจนขึ้นและบังคับการนำเมธอดและคุณสมบัติที่จำเป็นมาใช้ สิ่งนี้ช่วยรักษาความสม่ำเสมอของโค้ดและลดข้อผิดพลาด ทำให้มีประโยชน์อย่างยิ่งสำหรับโครงการขนาดใหญ่

คลาสเชิงนามธรรมเป็นเครื่องมือสำคัญใน Python ที่สนับสนุนการเขียนโปรแกรมเชิงวัตถุอย่างยืดหยุ่น ซึ่งช่วยเพิ่มความสามารถในการนำคลาสกลับมาใช้ใหม่และรักษาบำรุงโค้ดได้ง่ายขึ้น

คุณสามารถติดตามบทความข้างต้นโดยใช้ Visual Studio Code บนช่อง YouTube ของเรา กรุณาตรวจสอบช่อง YouTube ด้วย

YouTube Video