در دنیای برنامهنویسی، کلاسها و اشیاء یکی از مفاهیم بنیادی هستند که به برنامهنویسان امکان میدهند کدهای سازمانیافته و قابل اطمیانتری بنویسند. پایتون یکی از زبانهای برنامهنویسی محبوبی است که در استفاده از کلاسها و اشیاء تاکید دارد. در این مقاله، به بررسی کلاس و اشیا در پایتون میپردازیم و نحوه استفاده از آنها را آموزش میدهیم. پیشنهاد میکنیم از دیگر آموزشهای ما نیز دیدن فرمایید:
- لیست و نحوه کار با آن
- دیکشنری در پایتون
- Tuple در پایتون
- if در پایتون
- حلقه for
- حلقه while
- تابع در پایتون
- تبدیل نوع داده
مقدمه به کلاس و اشیا در پایتون
کلاسها و اشیا یکی از اصول برنامهنویسی شی گرا هستند. برنامهنویسی شیءگرا یک رویکرد برنامهنویسی است که به عناصر مختلفی مانند دادهها و عملیاتها(متدها) به عنوان اشیاء نگریسته و کدها را بر اساس این اشیاء ترتیب میدهد. به عبارت دیگر، در این رویکرد، کلیه اطلاعات و عملیاتهای مرتبط با یک مفهوم خاص را در یک کلاس تعریف میکنیم و از اشیاء این کلاس برای انجام عملیاتها استفاده میکنیم.
تعریف کلاس در پایتون
در پایتون، تعریف کلاس با استفاده از کلمه کلیدی class
آغاز میشود. نام کلاس باید با حروف بزرگ شروع شود و معمولاً باید نامی مناسب برای مفهوم یا واحدی که کلاس نمایانگر آن است، انتخاب شود. بعد از نام کلاس، میتوانیم دستورات مربوط به کلاس را درون یک بلاک تعریف کنیم.
class Person:
# ویژگیهای کلاس
def __init__(self, name, age):
self.name = name
self.age = age
# متد کلاس
def say_hello(self):
print(f"سلام، من {self.name} هستم و {self.age} سال دارم.")
در این تعریف کلاس Person
، دو متد اصلی تعریف شدهاند:
- متد
__init__
: این متد به عنوان متد سازنده (constructor) شناخته میشود و هنگامی که یک نمونه از کلاس ایجاد میگردد، اجرا میشود. این متد برای مقداردهی اولیه به ویژگیهای شیء استفاده میگردد. معمولاً پارامترهای متد سازنده برای تنظیم ویژگیهای(attribute) شیء استفاده میشوند. - متد
say_hello
: این متد یک متد کلاس است که پیامی را به همراه اطلاعات ویژگیهای شیء نمایش میدهد.
ایجاد نمونه از کلاس
پس از تعریف کلاس، میتوانیم نمونههای مختلفی از آن کلاس ایجاد کنیم. این نمونهها اشیاءی از کلاس هستند که میتوانند اطلاعات مختلفی داشته باشند.
# ایجاد نمونههایی از کلاس
person1 = Person("آرمان", 30)
person2 = Person("سارا", 25)
# فراخوانی متد کلاس بر روی نمونهها
person1.say_hello() # خروجی: "سلام، من آرمان هستم و 30 سال دارم."
person2.say_hello() # خروجی: "سلام، من سارا هستم و 25 سال دارم."
در این مثال، دو نمونه از کلاس Person
با نامها و سنهای مختلف ایجاد شدهاند. هر نمونه از کلاس Person
دارای ویژگیهای مخصوص به خود است و میتواند متدهای کلاس را صدا زد.
ویژگیها و متدهای کلاس
attribute یا ویژگیها (یا متغیرها) و متدهای کلاس تعیینکننده رفتار و ویژگیهای یک شیء هستند. ویژگیها معمولاً دادههایی را ذخیره میکنند و متدها عملیاتهایی را بر روی این دادهها انجام میدهند. در مثال قبل، ویژگیها name
و age
و متد say_hello
تعیینکننده رفتار کلاس Person
بودند.
وراثت در کلاسها
وراثت (Inheritance) یک مفهوم مهم در برنامهنویسی شیءگرا است که به برنامهنویس اجازه میدهد کلاس جدیدی را بر اساس یک کلاس موجود تعریف کند و ویژگیها و متدهای کلاس والد را به کلاس جدید ارث بری کند. این امکان به برنامهنویس این اجازه را میدهد که کدهای مشترک را میان کلاسها به اشتراک بگذارد و کدهای تکراری را کاهش دهد.
# تعریف کلاس مادر
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
pass
# تعریف کلاس فرزند
class Dog(Animal):
def speak(self):
return f"{self.name} واو واو!"
# تعریف کلاس فرزند دیگر
class Cat(Animal):
def speak(self):
return f"{self.name} میاو میاو!"
در این مثال، کلاس Animal
به عنوان کلاس والد تعریف شده است که یک ویژگی به نام name
دارد و متد speak
را تعریف کرده و آن را با pass
پیاده سازی میکند (pass دستوری است که برنامه از آن عبور می کند). سپس دو کلاس فرزند به نامهای Dog
و Cat
تعریف شدهاند که از کلاس Animal
ارث بری کردهاند و متد speak
را بازنویسی کردهاند.
# ایجاد نمونههایی از کلاسها
dog = Dog("Dog")
cat = Cat("Cat")
# فراخوانی متد speak بر روی نمونهها
print(dog.speak()) # خروجی: "dog واو واو!"
print(cat.speak()) # خروجی: "catمیاو میاو!"
در اینجا، دو نمونه از کلاسها ایجاد شدهاند و متد speak
بر روی هر یک از آنها فراخوانی شده است. هر کلاس فرزند ویژگیها و متدهای کلاس مادر را به ارث میبرد و میتواند آنها را بازنویسی کند.
مفهوم انتزاع در کلاس و اشیا در پایتون
انتزاع یکی از اصول مهم در برنامهنویسی شیءگرا است که به معنای مخفی کردن جزئیات پیچیده و نمایانسازی مفاهیم با سطوح بالا است. در پایتون، میتوانیم با استفاده از کلاسها و اشیاء این مفهوم را پیادهسازی کنیم.
به عنوان مثال، فرض کنید یک کلاس به نام Shape
داشته باشیم که ویژگیهایی مشترک برای اشیاء هندسی ارائه میدهد.
class Shape:
def __init__(self, color):
self.color = color
def area(self):
pass
def perimeter(self):
pass
در این کلاس، ویژگی color
به عنوان یک ویژگی مشترک برای اشیاء هندسی تعریف شده است، اما متدهای area
و perimeter
با pass
مقداردهی اولیه شدهاند. این کلاس یک مفهوم انتزاعی از یک شیء هندسی را نمایان میکند، اما جزئیات محاسبات را در خود ندارد.
حالا میتوانیم کلاسهایی برای اشیاء هندسی خاص ایجاد کنیم و محاسبات مربوط به مساحت و محیط را در این کلاسها پیادهسازی کنیم.
class Circle(Shape):
def __init__(self, color, radius):
super().__init__(color)
self.radius = radius
def area(self):
return 3.14 * self.radius ** 2
def perimeter(self):
return 2 * 3.14 * self.radius
class Rectangle(Shape):
def __init__(self, color, width, height):
super().__init__(color)
self.width = width
self.height = height
def area(self):
return self.width * self.height
def perimeter(self):
return 2 * (self.width + self.height)
در این مثال، دو کلاس Circle
و Rectangle
از کلاس Shape
ارث بری کردهاند و متدهای area
و perimeter
را بازنویسی کردهاند. این کلاسها جزئیات محاسبات مساحت و محیط را برای اشیاء هندسی خاص (دایره و مستطیل) ارائه میدهند.
# ایجاد نمونههایی از کلاسها
circle = Circle("قرمز", 5)
rectangle = Rectangle("آبی", 4, 6)
# فراخوانی متدها بر روی نمونهها
print(f"مساحت دایره {circle.color}: {circle.area()}")
print(f"محیط دایره {circle.color}: {circle.perimeter()}")
print(f"مساحت مستطیل {rectangle.color}: {rectangle.area()}")
print(f"محیط مستطیل {rectangle.color}: {rectangle.perimeter()}")
در نهایت، میتوانیم نمونههایی از کلاسها ایجاد کرده و متدها را بر روی آنها صدا بزنیم تا محاسبات مربوط به مساحت و محیط را انجام دهیم. این نمونه نشان دهنده مفهوم انتزاع از کلاس و اشیا در پایتون است.
پلیمورفیسم در کلاسها
پلیمورفیسم (Polymorphism) یا چندریختی مفهومی مهم در برنامهنویسی شیءگرا است که به برنامهنویس امکان میدهد تا یک عملیات یا متد را بر روی اشیاء مختلف اعمال کند. در پایتون، پلیمورفیسم با استفاده از ارثبری و بازنویسی متدها پیادهسازی میشود.
به عنوان مثال، در مثال قبل با استفاده از پلیمورفیسم متدهای area
و perimeter
را در کلاسهای Circle
و Rectangle
پیادهسازی کردیم. حالا میتوانیم یک تابع جداگانه بنویسیم که این متدها را بر روی اشیاء مختلف اجرا کند.
def print_area_and_perimeter(shape):
print(f"مساحت {shape.color}: {shape.area()}")
print(f"محیط {shape.color}: {shape.perimeter()}")
# ایجاد نمونههایی از کلاسها
circle = Circle("قرمز", 5)
rectangle = Rectangle("آبی", 4, 6)
# فراخوانی تابع با استفاده از پلیمورفیسم
print_area_and_perimeter(circle)
print_area_and_perimeter(rectangle)
در اینجا، تابع print_area_and_perimeter
یک شیء از کلاس Shape
را به عنوان ورودی میپذیرد و متدهای area
و perimeter
را بر روی آن اجرا میکند. به این ترتیب، میتوانیم همان تابع را بر روی اشیاء مختلفی از کلاسهای مختلف فراخوانی کنیم و عملیاتهای یکسانی را بر روی آنها انجام دهیم