คลาสนามธรรมใน 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 ด้วย