برنامه نویسی

راهنمای نهایی برنامه نویسی شی گرا در پایتون

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

چرا OOP؟

برنامه نویسی شی گرا مزایای زیادی برای برنامه نویس دارد که برخی از این مزایا در زیر ذکر شده است:

  • کد شما را قابل استفاده مجدد می کند
  • کد شما را تمیز می کند و ساختار واضحی به آن می دهد
  • حفظ کد شما را آسان می کند

ساختار OOP

  1. کلاس ها – اینها انواع داده های تعریف شده توسط کاربر هستند که به عنوان یک طرح اولیه برای اشیاء، متدها و ویژگی ها عمل می کنند یا محفظه هایی از اشیا، متدها و ویژگی ها هستند.
  2. اشیاء – اینها نمونه هایی از یک کلاس هستند که با داده های خاص تعریف شده ایجاد شده اند
  3. روش ها – اینها توابعی هستند که در داخل یک کلاس تعریف شده اند و رفتار اشیا را توصیف می کنند
  4. ویژگی ها – اینها وضعیت اشیاء یک کلاس را نشان می دهند

ایجاد اولین کلاس ما

ما می توانیم یک کلاس با استفاده از کلاس کلمه کلیدی به دنبال نام کلاس و یک دونقطه در پایان.
نحو:

class ClassName:
    statement1
        .
        .
    statementN
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

مثال 1: ایجاد کلاس خودرو

class Car:
    pass
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اگر انجام دهید print(type(Car)) خروجی زیر را دریافت خواهید کرد:

توضیحات تصویر

اشیاء کلاس

یک شی نمونه ای از یک کلاس است و باید دانست که می توانیم تا حد امکان از یک کلاس شی داشته باشیم. فرآیند ایجاد یک شیء کلاس را نمونه سازی شی نیز می نامند، شما فقط می توانید برای کلاسی که وجود دارد یک شی ایجاد کنید.
نحو:

object_name = ClassName()
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

مثال 2: ایجاد یک شی کلاس

audi = Car()
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

audi یک شی برای کلاس Car است

ایجاد یک کلاس و اشیاء آن

# creating a class Car
class Car:
    pass
# instantiating the Car class
car1 = Car()
car2 = Car()
# creating attributes for instances car1 and car2
car1.name = "Audi A7"
car2.name = "Nissan Demio"
car1.year_made = "2000"
car2.year_made = "1994"
# printing the output
print(car1.name, "was built in", car1.year_made)
print(car2.name, "was built in", car2.year_made)
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

خروجی:

توضیحات تصویر

روش های کلاس

اینها توابعی هستند که در داخل یک کلاس تعریف شده اند و رفتار اشیاء متصل به آن کلاس را توصیف می کنند. متدهای داخل کلاس همیشه خود را به عنوان اولین پارامتر در نظر می گیرند.
مثال 3: ایجاد متدهای کلاس

# creating a class Car
class Car:
    # initializing method(one of the special methods)
    # called everytime an instance is created
    # takes self always
    def __init__(self, name, year_made):
        self.name = name
        self.year_made = year_made
    # normal method to return the car info   
    def carInformation(self):
        return self.name + " was built in " + self.year_made

#instantiating class objects 
car1 = Car("Audi A7", "2000")
car2 = Car("Nissan Demio", "1994")
# calling the carInformation() method
print(car1.carInformation())
print(car2.carInformation())
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

خروجی:

توضیحات تصویر
توجه داشته باشید:
هر شی به هر چیزی که در کلاس موجود است دسترسی دارد، به عنوان مثال، شی car1 به روش دسترسی دارد carInformation().

بگذارید اکنون در مورد آن صحبت کنیم __init__ یا روش dunder init که با نام the سازنده، از این روش برای مقداردهی اولیه یک نمونه استفاده می شود و نام آن ثابت می شود (نمی توان به چیزی تغییر نام داد). داخل آن است __init__ روشی که ما صفات کلاس را جدا از ویژگی ها تعریف یا نمونه می کنیم self پارامتر دیگری است که __init__ روش می گیرد.

def __init__(self, name, year_made):
    self.name = name
    self.year_made = year_made
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

سایر روش های خاص مورد استفاده در کلاس ها

__str__ برای نمایش داده ها به روشی زیبا استفاده می شود
مثال:

# creating a class Car
class Car:
    def __init__(self, name, year_made):
        self.name = name
        self.year_made = year_made
    #the __str__ function for display pretty output 
    def __str__(self):
        return self.name
# instantiating an object
car1 = Car("Range Rover", "2019")
# calling the whole object
print(car1)
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

خروجی:

توضیحات تصویر

__repr__ برای ورود به سیستم و اشکال زدایی استفاده می شود
مثال:

# creating a class Car
class Car:
    def __init__(self, name, year_made):
        self.name = name
        self.year_made = year_made
    #the __repr__ function for display pretty output 
    def __repr__(self):
        return self.name
# instantiating an object
car1 = Car("Range Rover", "2019")
# calling the whole object
print(car1)
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

خروجی:
توضیحات تصویر
توجه داشته باشید:
را __str__ و __repr__ در طبیعت تفاوت چندانی ندارند

متغیرهای کلاس و نمونه

همانطور که کلاس های خود را ایجاد می کنید، ممکن است بخواهید با متغیرهای کلاس یا متغیرهای نمونه کار کنید یا با هر دو کار کنید، پس چگونه این دو تفاوت دارند؟ جدول زیر همه چیز را توضیح می دهد:

توضیحات تصویر
مثال 4: متغیرهای کلاس

# creating a class Car
class Car:
    # creating the class variable after class definition
    maximum_speed = "210 km/hr"
    # initializing method(one of the special methods)
    # called everytime an instance is created
    # takes self always
    def __init__(self, name, year_made):
        self.name = name
        self.year_made = year_made
    # normal method to return the car info   
    def carInformation(self):
        return self.name + " was built in " + self.year_made

#instantiating class objects 
car1 = Car("Audi A7", "2000")
# calling the carInformation() method
print(car1.carInformation())
# accessing class and instance variable using the object
print(car1.name, "has maximum speed of", car1.maximum_speed)
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

خروجی:

توضیحات تصویر

مثال 5: متغیرهای نمونه

# creating the class
class Car:
    # initializing method
    def __init__(self, name, year_made):
        # 2 instance variables name and year_made
        self.name = name
        self.year_made = year_made
#instantiating the class object   
car1 = Car("Audi A7", "2000")
# car1.name and car1.year_made accesses instance variables
print("Car name:", car1.name)
print("Year made:", car1.year_made)
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

خروجی:

توضیحات تصویر

وراثت

وراثت در برنامه نویسی شی گرا مفهومی است که در آن یک کلاس جدید با استفاده از یک کلاس موجود ایجاد می شود. همانطور که شما از یک کلاس ارث می برید، به این معنی است که متدها و ویژگی های آن کلاس را دریافت می کنید، به طور خلاصه، شما همه چیز موجود در آن کلاس را دریافت می کنید.

چرا ارث؟

وراثت امکان استفاده مجدد از کد را فراهم می کند، به این معنی که ما مجبور نیستیم یک کد را بارها و بارها بنویسیم و به راحتی می توانیم از یک روش با داده های مشابه یا تغییر یافته استفاده مجدد کنیم.

انواع ارث

  • وراثت منفرد – یک کلاس فرزند فقط از یک کلاس والدین ارث می برد
    نحو:
class ParentClass:
    statement(s)

class ChildClass(ParentClass):
    statement(s)
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

  • وراثت چندگانه – یک کلاس فرزند از چندین کلاس والد ارث می برد
    نحو:
class ParentClass:
    statement(s)

class AnotherParentClass:
    statement(s)

class ChildClass(ParentClass, AnotherParentClass):
    statement(s)
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

مثال 1: استفاده از وراثت

class Car:
    # creating class variables
    maximum_speed = "210 km/hr"
    number_of_tyres = 4
    # the dunder init method/initializer
    def __init__(self, name, year_made):
        self.name = name
        self.year_made = year_made

# class Minibus inheriting from class Car
class Minibus(Car):
    # __init__ method of class Minibus
    def __init__(self, name, year_made, price):
        self.name = name
        self.year_made = year_made
        self.price = price
    # method to return price
    def carPrice(self):
        return self.price
# instantiating the object for class Minibus
minbus1 = Minibus("Vanetti", "2013", "MWK4500000")
# printing data
print("Name:", minbus1.name)#name for Minibus class
print("Year made:", minbus1.year_made)#year for Minibus class
print("Maximum speeed:", minbus1.maximum_speed)#max_speed inherited from Car
print("Number of tyres:", minbus1.number_of_tyres)#number_of_tyres inherited from Car
print("Price:", minbus1.carPrice())#calling the carPrice() method in Minibus
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

خروجی:

توضیحات تصویر

کپسوله سازی

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

  • خصوصی – این ویژگی ها از خارج از خود کلاس نامرئی و غیرقابل دسترسی هستند

نحو:

def __init__(self, name, year_made):
    self.__year_made = year_made#this attribute is private
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

ما از زیرخط دوتایی استفاده می کنیم __ برای نشان دادن یک ویژگی خصوصی

مثال 2: ایجاد یک ویژگی خصوصی

# creating our class Car
class Car:
    # initializing attribute name via __init__
    def __init__(self, name):
        self.__name = name#this is a private attribute

#instantiating an object   
car1 = Car("BMW")
# printing the private attribute
print(car1.name)
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

خروجی:

توضیحات تصویر
ما یک خطا دریافت می کنیم زیرا ویژگی خصوصی در خارج از کلاس نامرئی و غیرقابل دسترسی است

  • محافظت شده – این ویژگی فقط از طریق یک کلاس فرعی قابل دسترسی است اما دسترسی به آنها در خارج از کلاس امکان پذیر است.

نحو:

def __init__(self, name, year_made):
    self._name = name#this attribute is protected
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

ما از یک خط زیر استفاده می کنیم _ برای نشان دادن یک ویژگی محافظت شده
مثال 3: ایجاد یک ویژگی محافظت شده

# creating our class Car
class Car:
    # initializing attribute name via __init__
    def __init__(self, name):
        self._name = name#this is a protected attribute

#instantiating an object   
car1 = Car("BMW")
# printing the protected attribute
print(car1._name)
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

خروجی:

توضیحات تصویر
برای دسترسی به ویژگی محافظت شده در خارج از کلاس، قبل از نام ویژگی از یک زیرخط استفاده می کنیم car1._name

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

پلی مورفیسم

Poly به معنای بسیاری و مورفیسم به معنای اشکال است، بنابراین چندشکلی به معنای داشتن اشکال متعدد است. در پایتون، چند شکلی به معنای استفاده از نام تابع یکسان به روش های مختلف است.
مثال 4: استفاده از پلی مورفیسم

# creating class Square
class Square:
    # initializer
    def __init__(self, side):
        self.side = side 
    # common method
    def calculate_area(self):
        return self.side * self.side
# creating class Triangle
class Triangle:
    # initializer
    def __init__(self, base, height):
        self.base = base
        self.height = height
    # common method
    def calculate_area(self):
        return 0.5 * self.base * self.height
# instantiating class objects
sq = Square(6)
tri = Triangle(2, 7)
# printing results
print("Area of square: ", sq.calculate_area())
print("Area of triangle: ", tri.calculate_area())
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

خروجی:

توضیحات تصویر
در دو کلاس خود یک متد مشترک ایجاد کرده ایم calculate_area() که به طرق مختلف استفاده می شود، یعنی محاسبه مساحت مربع و مثلث.

نتیجه

به طور خلاصه، تسلط بر مفاهیم شی گرا یک مهارت ضروری برای هر توسعه دهنده است. پیروی از یک پارادایم شی گرا هنگام نوشتن کد، آن را تمیزتر، قابل نگهداری و قابل استفاده مجدد می کند.

نوشته های مشابه

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

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

دکمه بازگشت به بالا