کلاس Abstract در پایتون یکی از اصول اساسی در توسعه نرمافزارهای مدرن به شمار میرود و پایتون نیز این قابلیت را برای برنامهنویسان خود فراهم کرده است. کلاس Abstract در پایتون شامل چهار اصل کلیدی است که یکی از این اصول، انتزاع «Abstraction» نام دارد. در زبان برنامهنویسی پایتون، برای پیادهسازی اصل انتزاع از کلاسهای انتزاعی یا همان کلاسهای Abstract استفاده میشود که در این مقاله از سری مقالههای مجله پی استور به توضیح آن پرداختهایم.
مقدمه
کلاسهای انتزاعی «Abstract Classes» در پایتون ابزاری برای تعریف ساختار کلی یک کلاس هستند که نمیتوانند بهطور مستقیم ایجاد شوند. این کلاسها معمولاً بهعنوان الگوهایی برای ایجاد کلاسهای دیگر استفاده میشوند. در پایتون، کلاسهای انتزاعی با استفاده از ماژول abc تعریف میشوند. این کلاسها میتوانند متدهایی داشته باشند که نیاز به پیادهسازی در کلاسهای فرزند دارند. هدف اصلی کلاسهای انتزاعی این است که کلاسهای فرزند را مجبور کنند تا متدهای خاصی را پیادهسازی کنند، بهاینترتیب برنامهنویس میتواند اطمینان حاصل کند که کلاسهای فرزند ویژگیهای مشخصی دارند. استفاده از کلاسهای انتزاعی به ایجاد کدهای مقیاسپذیرتر و قابل نگهداریتر کمک میکند.
مفهوم انتزاع در شی گرایی
در پایتون به معنای پنهان کردن جزئیات پیادهسازی و نمایش فقط ویژگیها و متدهای ضروری است که برای تعامل با شی مورد نیاز هستند. این کار معمولا با استفاده از کلاس Abstract در پایتون «Abstract Classes» و متدهای انتزاعی «Abstract Methods» انجام میشود. انتزاع در شیگرایی با استفاده از ماژول abc پیادهسازی میشوند، که به ما اجازه میدهد کلاسهای پایهای ایجاد کنیم که نمیتوانند مستقیما نمونهسازی شوند و باید توسط کلاسهای فرزند پیادهسازی شوند.کلاس Abstract در پایتون یعنی تعریف کلاسها و متدهایی که فقط رابطها را مشخص میکنند و جزئیات پیادهسازی را مخفی میکنند، تا تنها ویژگیهای لازم برای کار با شی قابل دسترس باشند.
کلاس های پایه انتزاعی ABCs در پایتون
کلاس Abstract در پایتون متدهایی را تعریف میکنند که باید توسط زیرکلاسهایشان پیادهسازی شوند، تا زیرکلاسها از یک ساختار یکسان پیروی کنند. کلاس Abstract در پایتون به شما امکان میدهند رابطهای مشترکی تعریف کنید که زیرکلاسهای مختلف بتوانند آن را پیادهسازی کنند و در عین حال سطحی از انتزاع را اعمال میکنند. پایتون ماژول abc را برای تعریف ABCها و اجباری کردن پیادهسازی متدهای انتزاعی در زیرکلاسها ارائه میدهد.
from abc import ABC, abstractmethod # Define an abstract class class Animal(ABC): @abstractmethod def sound(self): pass # This is an abstract method, no implementation here. # Concrete subclass of Animal class Dog(Animal): def sound(self): return "Bark" # Providing the implementation of the abstract method # Create an instance of Dog dog = Dog() print(dog.sound()) # Output: Bark
- کلاس پایه انتزاعی: کلاس Animal یک کلاس انتزاعی است که از ABC «کلاس پایه انتزاعی» ارثبری میکند. این کلاس را نمیتوان مستقیماً نمونهسازی کرد، زیرا شامل یک متد انتزاعی به نام ()sound است. دکوراتور abstractmethod@ برای علامتگذاری متد ()sound بهعنوان متد انتزاعی استفاده میشود. این بدان معناست که هر زیرکلاسی برای نمونهسازی باید این متد را پیادهسازی کند.
- زیرکلاس عادی: کلاس Dog یک زیرکلاس از Animal است که پیادهسازی متد ()sound را ارائه میدهد. این امکان را فراهم میکند که کلاس ()Dog نمونهسازی شده و مورد استفاده قرار گیرد.
- نمونهسازی: ما یک نمونه از کلاس Dog ایجاد میکنیم و متد ()sound را فراخوانی میکنیم که مقدار Bark را برمیگرداند.
متدهای انتزاعی در پایتون
متدهای انتزاعی، متدهایی هستند که در یک کلاس انتزاعی تعریف میشوند اما پیادهسازی ندارند. این متدها بهعنوان الگویی برای زیرکلاسها عمل میکنند و اطمینان میدهند که زیرکلاسها پیادهسازی مخصوص به خود را ارائه دهند.
from abc import ABC, abstractmethod class Animal(ABC): @abstractmethod def make_sound(self): pass # Abstract method, no implementation here
متد ()make_sound در کلاس Animal یک متد انتزاعی است، بنابراین هیچ کدی داخل آن وجود ندارد.
متدهای عادی در پایتون
متدهای عادی متدهایی هستند که در یک کلاس انتزاعی پیادهسازی کامل دارند. این متدها میتوانند توسط زیرکلاسها به ارث برده شوند و مستقیما بدون نیاز به بازتعریف مورد استفاده قرار گیرند.
from abc import ABC, abstractmethod class Animal(ABC): @abstractmethod def make_sound(self): pass # Abstract method, to be implemented by subclasses def move(self): return "Moving" # Concrete method with implementation
متد ()move در کلاس Animal یک متد عادی است. این متد پیادهسازی شده و نیازی نیست که در کلاس Dog بازنویسی شود.
ویژگی های انتزاعی در پایتون
ویژگیهای انتزاعی مشابه متدهای انتزاعی عمل میکنند اما برای ویژگیها استفاده میشوند. این ویژگیها با دکوراتور property@ تعریف شده و با استفاده از abstractmethod@ بهعنوان انتزاعی علامتگذاری میشوند. زیرکلاسها باید این ویژگیها را پیادهسازی کنند.
from abc import ABC, abstractmethod class Animal(ABC): @property @abstractmethod def species(self): pass # Abstract property, must be implemented by subclasses class Dog(Animal): @property def species(self): return "Canine" # Instantiate the concrete subclass dog = Dog() print(dog.species)
- species یک ویژگی انتزاعی در کلاس Animal است که با abstractmethod@ علامتگذاری شده است.
- کلاس Dog ویژگی species را پیادهسازی میکند و آن را به یک زیرکلاس عادی تبدیل میکند که میتوان آن را نمونهسازی کرد.
- ویژگیهای انتزاعی تضمین میکنند که یک زیرکلاس پیادهسازی ویژگی مربوطه را ارائه دهد.
نمونه سازی کلاس های انتزاعی در پایتون
کلاسهای انتزاعی را نمیتوان مستقیما نمونهسازی کرد. این به این دلیل است که این کلاسها شامل یک یا چند متد یا ویژگی انتزاعی هستند که پیادهسازی ندارند. تلاش برای نمونهسازی یک کلاس انتزاعی منجر به خطای TypeError میشود.
from abc import ABC, abstractmethod class Animal(ABC): @abstractmethod def make_sound(self): pass # Trying to instantiate the abstract class directly # This will raise an error: # animal = Animal() # TypeError: Can't instantiate abstract class Animal with abstract methods make_sound
کلاس ()Animal انتزاعی است زیرا متد ()make_sound را بهعنوان یک متد انتزاعی دارد.
اگر تلاش کنید که مستقیما ()Animal را نمونهسازی کنید مثلاً animal = Animal، پایتون یک ()TypeError ایجاد میکند زیرا نمیتوان کلاسی که متدهای انتزاعی پیادهسازینشده دارد را نمونهسازی کرد.
فقط زیرکلاسهایی که تمام متدهای انتزاعی را پیادهسازی کردهاند میتوانند نمونهسازی شوند.
کلاس Abstract در پایتون، با استفاده از ماژول abc (Abstract Base Class)، برای ایجاد کلاسهای پایهای استفاده میشود که نمیتوانند مستقیما نمونهسازی شوند و هدف آنها ایجاد قالبی برای کلاسهای فرزند است. به این صورت که کلاسهای فرزند باید متدهای خاصی را پیادهسازی کنند.
نتیجهگیری
کلاسهای Abstract در پایتون به برنامهنویسان این امکان را میدهند که طراحی کدهای خود را ساختاریافته و مدرن کنند. این کلاسها به جلوگیری از پیادهسازی نادرست یا ناقص متدها در کلاسهای فرزند کمک میکنند و از پیادهسازی متدهای انتزاعی برای الزام به پیادهسازی آنها در کلاسهای فرزند استفاده میکنند. همچنین، کلاسهای Abstract به افزایش خوانایی کد و اطمینان از پیروی کلاسهای فرزند از یک الگوی مشخص کمک میکنند. این ویژگیها بهویژه زمانی که نیاز به طراحی سیستمهای پیچیده با قوانین خاص داریم، بسیار مفید هستند و به ایجاد کدهای منظم و مقیاسپذیر کمک میکنند.