برنامه‌نویسی شی‌گرا در پایتون: مفاهیم متوسط

برنامه‌نویسی شی‌گرا در پایتون: مفاهیم متوسط

برنامه‌نویسی شی‌گرا (Object-Oriented Programming یا OOP) یک پارادایم برنامه‌نویسی قدرتمند است که به شما امکان می‌دهد برنامه‌های خود را به صورت مجموعه‌ای از اشیاء سازماندهی کنید. این اشیاء دارای داده‌ها (ویژگی‌ها) و رفتارهایی (متدها) هستند که بر روی آن داده‌ها عمل می‌کنند. در این مقاله، به بررسی مفاهیم متوسط برنامه‌نویسی شی‌گرا در پایتون می‌پردازیم، با فرض اینکه شما با مفاهیم پایه مانند کلاس‌ها و اشیاء آشنا هستید.

وراثت (Inheritance)

وراثت یکی از مهم‌ترین مفاهیم OOP است. این مفهوم به شما امکان می‌دهد کلاس‌های جدیدی را بر اساس کلاس‌های موجود ایجاد کنید. کلاس جدید (کلاس فرزند یا زیرکلاس) تمام ویژگی‌ها و متدهای کلاس موجود (کلاس والد یا ابرکلاس) را به ارث می‌برد و می‌تواند ویژگی‌ها و متدهای جدیدی را نیز اضافه کند یا متدهای موجود را بازنویسی (Override) کند.

وراثت به شما کمک می‌کند تا از تکرار کد جلوگیری کنید و کدی قابل نگهداری‌تر و سازمان‌یافته‌تر ایجاد کنید. به عنوان مثال، فرض کنید یک کلاس `Animal` داریم که ویژگی‌های عمومی حیوانات مانند `name` و `age` را دارد و متدهایی مانند `eat()` و `sleep()` را تعریف می‌کند. سپس می‌توانیم کلاس‌های `Dog` و `Cat` را از کلاس `Animal` مشتق کنیم. کلاس‌های `Dog` و `Cat` به طور خودکار ویژگی‌ها و متدهای `Animal` را به ارث می‌برند و می‌توانند ویژگی‌ها و متدهای خاص خود را نیز اضافه کنند، مانند `bark()` برای `Dog` و `meow()` برای `Cat`.

class Animal:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def eat(self):
        print(f"{self.name} is eating.")

    def sleep(self):
        print(f"{self.name} is sleeping.")

class Dog(Animal):
    def __init__(self, name, age, breed):
        super().__init__(name, age)
        self.breed = breed

    def bark(self):
        print("Woof!")

class Cat(Animal):
    def __init__(self, name, age, color):
        super().__init__(name, age)
        self.color = color

    def meow(self):
        print("Meow!")

my_dog = Dog("Buddy", 3, "Golden Retriever")
my_cat = Cat("Whiskers", 2, "Gray")

my_dog.eat()  # Output: Buddy is eating.
my_dog.bark()  # Output: Woof!
my_cat.sleep() # Output: Whiskers is sleeping.
my_cat.meow()  # Output: Meow!

چندریختی (Polymorphism)

چندریختی به معنای “چند شکلی” است. این مفهوم به شما امکان می‌دهد اشیاء مختلف را به صورت یکسان مورد استفاده قرار دهید. به عبارت دیگر، یک متد می‌تواند در کلاس‌های مختلف به شکل‌های مختلف پیاده‌سازی شود. این امکان را فراهم می‌کند که کدی بنویسید که با انواع مختلف اشیاء کار کند بدون اینکه نیاز به دانستن نوع دقیق هر شیء داشته باشید.

در پایتون، چندریختی به طور پیش‌فرض پشتیبانی می‌شود. به عنوان مثال، در مثال وراثت بالا، هر دو کلاس `Dog` و `Cat` متد `eat()` را به ارث برده‌اند. با این حال، پیاده‌سازی این متد می‌تواند در هر کلاس متفاوت باشد. چندریختی همچنین می‌تواند از طریق رابط‌ها (Interfaces) یا کلاس‌های انتزاعی (Abstract Classes) پیاده‌سازی شود.

class Animal:
    def __init__(self, name):
        self.name = name

    def make_sound(self):
        print("Generic animal sound")

class Dog(Animal):
    def make_sound(self):
        print("Woof!")

class Cat(Animal):
    def make_sound(self):
        print("Meow!")

def animal_sound(animal):
    animal.make_sound()

my_dog = Dog("Buddy")
my_cat = Cat("Whiskers")

animal_sound(my_dog)  # Output: Woof!
animal_sound(my_cat)  # Output: Meow!

کپسوله‌سازی (Encapsulation)

کپسوله‌سازی به معنای پنهان کردن جزئیات پیاده‌سازی داخلی یک کلاس و ارائه یک رابط کاربری ساده و مشخص برای تعامل با آن است. این کار به شما کمک می‌کند تا از دسترسی مستقیم به داده‌های داخلی کلاس جلوگیری کنید و از تغییرات ناخواسته جلوگیری کنید. در پایتون، کپسوله‌سازی با استفاده از قرارداد نام‌گذاری (Naming Convention) و ویژگی‌های دسترسی (Access Modifiers) پیاده‌سازی می‌شود.

به طور معمول، ویژگی‌هایی که با یک خط زیر (`_`) شروع می‌شوند، به عنوان ویژگی‌های محافظت‌شده (Protected) در نظر گرفته می‌شوند و نباید مستقیماً از خارج از کلاس دسترسی پیدا کرد. ویژگی‌هایی که با دو خط زیر (`__`) شروع می‌شوند، به عنوان ویژگی‌های خصوصی (Private) در نظر گرفته می‌شوند و دسترسی به آنها از خارج از کلاس بسیار دشوار است (اگرچه غیرممکن نیست). متدهای خصوصی نیز به همین ترتیب نام‌گذاری می‌شوند.

class BankAccount:
    def __init__(self, account_number, balance):
        self._account_number = account_number  # Protected attribute
        self.__balance = balance  # Private attribute

    def deposit(self, amount):
        if amount > 0:
            self.__balance += amount
            print(f"Deposited {amount}. New balance: {self.__balance}")
        else:
            print("Invalid deposit amount.")

    def withdraw(self, amount):
        if amount > 0 and amount <= self.__balance:
            self.__balance -= amount
            print(f"Withdrew {amount}. New balance: {self.__balance}")
        else:
            print("Insufficient funds or invalid withdrawal amount.")

    def get_balance(self):
        return self.__balance

my_account = BankAccount("1234567890", 1000)
my_account.deposit(500)  # Output: Deposited 500. New balance: 1500
my_account.withdraw(200) # Output: Withdrew 200. New balance: 1300
print(my_account.get_balance()) # Output: 1300
# print(my_account.__balance) # This will raise an AttributeError

انتزاع (Abstraction)

انتزاع به معنای نمایش فقط اطلاعات ضروری و پنهان کردن جزئیات پیچیده پیاده‌سازی است. این کار به شما کمک می‌کند تا با سیستم‌های پیچیده به صورت ساده‌تر و قابل فهم‌تری تعامل داشته باشید. کلاس‌های انتزاعی و رابط‌ها ابزارهایی برای پیاده‌سازی انتزاع هستند.

در پایتون، کلاس‌های انتزاعی با استفاده از ماژول `abc` (Abstract Base Classes) پیاده‌سازی می‌شوند. یک کلاس انتزاعی نمی‌تواند به طور مستقیم نمونه‌سازی شود و باید توسط کلاس‌های دیگر ارث برده شود. کلاس‌های انتزاعی می‌توانند متدهای انتزاعی داشته باشند که باید توسط کلاس‌های فرزند پیاده‌سازی شوند.

from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    def area(self):
        pass

    @abstractmethod
    def perimeter(self):
        pass

class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius

    def area(self):
        return 3.14159 * self.radius * self.radius

    def perimeter(self):
        return 2 * 3.14159 * self.radius

class Rectangle(Shape):
    def __init__(self, width, height):
        self.width = width
        self.height = height

    def area(self):
        return self.width * self.height

    def perimeter(self):
        return 2 * (self.width + self.height)

# my_shape = Shape() # This will raise a TypeError
my_circle = Circle(5)
my_rectangle = Rectangle(4, 6)

print(my_circle.area()) # Output: 78.53975
print(my_rectangle.area()) # Output: 24

نتیجه‌گیری

برنامه‌نویسی شی‌گرا یک پارادایم قدرتمند است که به شما امکان می‌دهد برنامه‌های پیچیده را به صورت سازمان‌یافته‌تر و قابل نگهداری‌تر ایجاد کنید. مفاهیم وراثت، چندریختی، کپسوله‌سازی و انتزاع ابزارهای مهمی برای پیاده‌سازی OOP هستند. با درک این مفاهیم، می‌توانید برنامه‌های پایتون خود را به سطح بالاتری ببرید و از مزایای OOP بهره‌مند شوید.

بدون دیدگاه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *