“هر احمقی می تواند بداند. نکته این است که بفهمیم.» – آلبرت انیشتین

برنامه نویسی شی گرا یک روش محبوب برای نوشتن برنامه های کامپیوتری است.

به همین دلیل، همه برنامه نویسان باید بدانند که OOP چیست، از چه زبان هایی می توانید برای برنامه نویسی به این روش استفاده کنید و چرا اهمیت دارد.

هنگامی که به زبان ساده از استیو جابز پرسیده شد که دقیقاً نرم افزار شی گرا چیست، گفت:

اشیاء مانند مردم هستند. آنها چیزهایی زنده و تنفس می کنند که در درون خود دانشی در مورد روش انجام کارها دارند و حافظه درون خود دارند تا بتوانند چیزها را به خاطر بسپارند.

و به جای تعامل با آنها در سطح بسیار پایین، شما در سطح بسیار بالایی از انتزاع با آنها تعامل دارید، مانند آنچه ما در اینجا انجام می دهیم. با این حال، در واقع چه معنایی در کد دارد؟

این راهنما اصول اولیه را پوشش می‌دهد، از جمله برخی از مفاهیمی که اکثر آموزش‌ها قادر به پرداختن به آنها نیستند، مانند:

  • چه چیزی داخلش هست__” ؟
  • روش ها و عملکردها چگونه متفاوت هستند؟
  • پارامتر “self” در پایتون به چه معناست؟

هدف این راهنما کمک به شما در درک اصول برنامه نویسی شی گرا در پایتون است. پس بیایید شیرجه بزنیم

آنچه را پوشش خواهیم داد:

  1. OOP چیست؟
  2. کلاس ها و نمونه های کلاس ها چیست؟
  3. روش ایجاد کلاس با “__init__”
  4. کلمه کلیدی خود چیست؟
  5. متغیرهای نمونه در مقابل متغیرهای کلاس
  6. روش‌ها در OOP – تصحیح قیمت تورم مثال
  7. از اینجا به کجا برویم

این آموزش فرض می کند که شما اصول برنامه نویسی پایتون را می دانید.

به راحتی می توانید از کد و تصاویر پست های موجود در مخزن GitHub زیر استفاده کنید.

OOP چیست؟

pexels-binyamin-melish-106399
عکس بنیامین ملیش از Pexels

فرض کنید شما یک شرکت ساختمانی را اداره می کنید. کسب و کار شما در حال گسترش است. هدف شما ساختن 100 خانه جدید است.

شما تصمیم می گیرید که همه خانه ها کمابیش ساختار یکسانی داشته باشند.

با انجام این کار، می توانید هزینه ها را کاهش دهید و تمام پیچیدگی های مربوط به ساخت خانه را بهتر مدیریت کنید.

هر خانه با استفاده از همان پلان خانه ساخته خواهد شد که توسط یک معمار طراحی شده است.

pexels-jeshootscom-834892
عکس از JESHOOTS.com

به جای اینکه هر خانه را از ابتدا طراحی کنید، تمام خانه هایی که می سازید دارای پلان مشابهی خواهند بود.

در این صورت می توان گفت که شرکت شما خانه ها را به صورت خانه محور می سازد.

در این قیاس:

  • یک نقاشی = یک کلاس
  • خانه = نمونه ای از یک کلاس یا شی
  • ساختمان خانه گرا = برنامه نویسی شی گرا

همانطور که ساختمان خانه گرا روشی کارآمد برای ساخت خانه های جدید است، برنامه نویسی شی گرا نیز روشی کارآمد برای نوشتن برنامه های کامپیوتری است.

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

به همین ترتیب، برنامه نویسی با نوشتن برنامه هایی شروع می شود که دستورالعمل هایی را برای انجام برخی کارها به روشی خاص ارائه می دهند.

اما در برنامه نویسی شی گرا، شما نقشه هایی برای مدیریت و ایجاد داده ها ایجاد می کنید.

با ساخت و ساز خانه محور، نقشه خانه را ترسیم می کنید و تصمیم می گیرید که چه مصالحی برای ساخت آن نیاز است.

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

مدیریت تدارکات ساخت خانه ها زمانی که یک طرح خانه برای انتخاب دارید آسان تر است و می توانید تعداد خانه ها را به هر تعداد که می خواهید تغییر دهید. همین امر در مورد برنامه نویسی کد و شی گرا نیز صدق می کند.

اصول اصلی OOP

همانطور که شیوه های متفاوتی برای ساخت خانه وجود دارد، شیوه های خوبی نیز در برنامه نویسی شی گرا وجود دارد.

برای نوشتن کد عالی، OOP از چهار ستون پیروی می کند:

  • چند شکلی – توانایی یک شی در شکل های مختلف
  • وراثت – کلاس های فرزند دارای ویژگی هایی از کلاس های والد هستند
  • کپسوله سازی – از داده ها و روش ها در برابر سوء استفاده های خارجی با اتصال آنها به یکدیگر محافظت می کند
  • انتزاع – با پنهان کردن جزئیات غیر ضروری از کاربر، پیچیدگی را کنترل می کند.

برای ارتباط این موضوع با مثال ساختمان خانه محور ما:

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

در مثال‌های بالا، در مورد مفاهیم کلی صحبت کرده‌ایم – نه کد پشت هر مفهوم. و ما کد را در اینجا پوشش نمی دهیم. با این حال، می توانید ایده ای در مورد اینکه هر مفهوم چیست و چرا اهمیت دارد، به دست آورید.

اگر می خواهید در مورد کد بیشتر بدانید، می توانید این آموزش را مطالعه کنید.

پیشنهاد می‌کنیم بخوانید:  map()، filter() و reduce() در پایتون با Examples

آیا می توانید کدهای شی گرا را به زبان های مختلف بنویسید؟

استفاده از برنامه نویسی شی گرا (OOP) در زبان های برنامه نویسی مختلف امکان پذیر است، اما ممکن است از تکنیک های متفاوتی استفاده کنید. روی زبان و نوع برنامه ای که می سازید.

برای مثال، جاوا را در نظر بگیرید. این به طور خاص برای OOP طراحی شده است. در جاوا، کلاس ها و اشیاء را برای ساختار کد خود ایجاد می کنید.

مانند ایجاد نقشه ها و سپس ساختن با آن نقشه ها.

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

در مورد پایتون، این یک زبان برنامه نویسی بسیار انعطاف پذیر است. می‌توانید از OPP در پایتون استفاده کنید، جایی که آن طرح‌ها را با کلاس‌ها می‌سازید.

همچنین می‌توان از آن برای برنامه‌نویسی رویه‌ای استفاده کرد، جایی که شما دستورالعمل‌های ساده مانند لیست کارهایی را ارائه می‌کنید.

استفاده از OOP هنگام کار می تواند بسیار مفید باشد روی پروژه های نرم افزاری پیچیده

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

کلاس ها و نمونه های کلاس ها (یا اشیاء) چیست؟

نمونه ها بر اساس ایجاد می شوند روی یک کلاس. کلاس ها نقشه هایی هستند که نشان می دهند نمونه ای از یک کلاس چگونه به نظر می رسد.

متغیرهای نمونه دارای داده هایی منحصر به فرد برای آن نمونه هستند که بین همه کلاس ها به اشتراک گذاشته نمی شود.

هر نمونه مانند هر خانه دارای ویژگی های منحصر به فردی است.

اما، چگونه همه اینها در کد واقعی به نظر می رسد؟

روش ایجاد کلاس ها به صورت دستی:

class house():
    pass

house1 = house()
house2 = house()

house1.address = 1234;
house1.state = "california"
house1.Alarm = False;
house1.price = 300000;

house2.address = 5678;
house2.state = "texas"
house2.Alarm = True;
house2.price = 100000;

print(house1.state)
print(house2.price)

>>> california
>>> 100000
به صورت دستی

در خط اول، بدون هیچ چیز از پیش تعریف شده، طرحی برای خانه ایجاد کردیم.

این مانند زمانی است که یک معمار یک برگه کاغذ خالی دارد که طرح اولیه یک خانه است – ورق وجود دارد، اما هیچ چیزی در آن وجود ندارد.

سپس ما 2 خانه با ویژگی های مشابه ایجاد کردیم:

  • آدرس خانه
  • وضعیت خانه
  • اگه زنگ داره یا نه
  • قیمت خانه

اما برای اضافه کردن هر مشخصه، باید مقدار را به صورت دستی درج می کردیم.

اما، اگر بخواهید 100 خانه با ویژگی های فردی پر شده برای هر خانه ایجاد کنید، چه؟

افزودن تمام این ویژگی های کلاس به صورت دستی بسیار خسته کننده و وقت گیر است.

بیایید ببینیم چگونه می توانیم این را ساده کنیم:

روش ایجاد کلاس با __init__:

class house():
    def __init__(self, address, state, Alarm, price):
        self.address = address
        self.state = state
        self.Alarm = Alarm
        self.price = price


house1 = house(1234, "california", False , 300000)

house2 = house(5678, "texas", True , 100000)

print(house1.state)
print(house2.price)

>>> california
>>> 100000
خودکارpy-1

خروجی این بلوک کد و خروجی قسمت قبل یکسان است.

اولی 18 خط دارد و ایجاد خانه دشوار است. دومی 14 خط دارد و به راحتی می توان خانه ایجاد کرد.

این ماهیت برنامه نویسی است – خودکار کردن چیزها و آسان کردن آنها.

ممکن است در مورد کد بالا سؤالاتی داشته باشید. بیایید با جزئیات بیشتری به آن نگاه کنیم.

چیست __init__?

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

دارای زیرخط دوگانه است تا مفسر بتواند بین متغیرهای کد و متدهای ویژه پایتون تمایز قائل شود.

استفاده از زیرخط ها خارج از محدوده این مقاله است، بنابراین فقط بدانید که اینها در اینجا چه می کنند.

ویژگی هایی که می خواهید در کنار سازنده قرار دارند.

اما، چرا یک متغیر “خود” در آنجا وجود دارد؟ و خود به چه معناست؟

چیست self کلمه کلیدی؟

self کلمه کلیدی فقط به شما امکان می دهد بدانید که یک ویژگی خاص از یک شی به شیء دیگر تغییر می کند.

در زیر مثالی از آنچه منظور من است آورده شده است:

self.address = address

همان نوشتن است:

house1.address = 1234;

با این حال، با نوشتن:

  def __init__(self, address, state, alarm, price):
        self.address = address
        self.state = state
        self.alarm = alarm
        self.price = price

شما می گویید که می خواهید یک خانه ایجاد کنید (__init__) با چهار ویژگی آدرس، وضعیت، زنگ هشدار و قیمت.

شما می گویید که در هر نمونه ای از کلاس، .مشخصه یک خانه همان چیزی است که در پارامترها وجود دارد.

به این ترتیب هنگام نوشتن:

house1 = house(1234, "california", False , 300000)

فکر خواهد کرد:

house1.address = 1234
house1.state = "california"
house1.alarm = False
house1.price = 300000

توجه: به جای استفاده از self، می توانید از هر متغیری که می خواهید استفاده کنید. این فقط برای یک قرارداد است که به نمونه کلاسی که استفاده می کنیم ارجاع دهد.

همچنین، به این ترتیب، به راحتی به هر ویژگی یک کلاس مقدار می دهید.

چرا این همه سردرگمی؟

به این ترتیب، می توانید ویژگی هایی را بر اساس سایر ویژگی هایی که باید دوباره اعلام شوند ایجاد کنید:

class house():
    def __init__(self, address, street , state):
        self.address = address
        self.street = street
        self.state = state

        self.completeAddress = str(address) + " " + state


house = house(1234, "california", "awesome road")

print(house.completeAddress)

>>>1234 awesome road
آدرس کامل.py

با خود، می توانیم ویژگی های دیگری را بر اساس ایجاد کنیم روی را __init__ مولفه های.

__init__ تابع a ندارد completeAddress پارامتر.

بر اساس ساخته شد روی آدرس، خیابان و مقادیر ایالت.

(توجه داشته باشید که این یک آدرس تصادفی است و واقعی نیست.)

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

بنابراین در حال حاضر دیدیم که می‌توانیم خانه‌های زیادی را براساس یک طرح خانه بسازیم.

اما، ما هنوز تمام نشده است. بیایید بگوییم که شما می خواهید هر خانه ای یک فرش اتاق نشیمن بزرگ داشته باشد

pexels-pixabay-carpet
عکس Pixabay از Pexels

هر اتاق دارای یکسان فرش در هر خانه چیزهای دیگر در خانه، مانند مبل، می تواند باشد ناهمسان.

پیشنهاد می‌کنیم بخوانید:  سرویس فایل‌های استاتیک با Node و Express.jsدر این مقاله، ما قصد داریم یک اپلیکیشن ساده برای ارائه فایل‌های استاتیک مانند فایل‌های HTML، فایل‌های CSS و تصاویر با استفاده از Node.js و Express بسازیم. پیکربندی پروژه و نصب Express برای شروع، بیایید با اجرای دستور init در یک پروژه Node.js جدید ایجاد کنیم.

بیایید همچنین فرض کنیم که همه خانه ها یک مبل خواهند داشت.

بنابراین در OOP، مبل هست یک متغیرنمونه، زیرا هر نمونه از کلاس مقدار خاص خود را برای آن ویژگی خواهد داشت.

به عنوان مثال، ویژگی های:

  • نشانی
  • حالت
  • زنگ خطر. هشدار
  • قیمت

همه متغیرهای نمونه هستند، زیرا برای هر نمونه منحصر به فرد هستند.

بنابراین مبل یک متغیرنمونه – اما فرش یک متغیر کلاس

از آنجایی که یک متغیر کلاس است، همه نمونه های کلاس دارای آن متغیر خواهند بود.

مثال دیگری از متغیر کلاس نام شرکتی است که خانه ها را می سازد:

class house():

    company_name = "Awesome building company"

    def __init__(self, address, state, Alarm, price):
        self.address = address
        self.state = state
        self.Alarm = Alarm
        self.price = price


house1 = house(1234, "california", False , 300000)

house2 = house(5678, "texas", True , 100000)
automaticV2.py

متغیر کلاس در اینجا نام شرکت است: “شرکت ساختمانی عالی”.

مجدداً، متغیری که حاوی داده‌های خاص نمونه است، متغیر نمونه نامیده می‌شود – بین کلاس‌ها به اشتراک گذاشته نمی‌شود.

متغیرهایی مانند حالت یا قیمت متغیرهای نمونه هستند.

  • متغیرهای نمونه = ویژگی های خاص هر خانه (متفاوت)
  • متغیرهای کلاس = نام شرکتی که خانه را می سازد (همان)

تمام نمونه‌های کلاس‌ها شامل متغیرهای کلاس هستند و هر نمونه از یک کلاس، متغیرهای نمونه خود را دارد.

اگر متغیرها در طول زمان تغییر کنند چه؟

قیمت خانه ها و تورم در سال 1402 واقعاً بالا است. آنقدر بالا که قیمت خانه ها دیگر ارزش واقعی آنها را نشان نمی دهد. قیمت خانه – یا هر موردی – می تواند در طول زمان تغییر کند روی عوامل مختلف

به عنوان مثال، با گذشت زمان، یک خانه که 50000 دلار ارزش داشت، اکنون به دلیل تورم 8 درصد، قیمتی معادل 54000 دلار خواهد داشت.

قیمتش بالا رفته خب حالا شما مشکل دارید:

با توجه به اینکه تورم در حال حاضر 8 درصد است، چگونه می خواهید قیمت جدید خانه را به روز کنید؟

یکی از پاسخ های این سوال استفاده از روشی برای به روز رسانی قیمت است.

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

روش‌ها در OOP – تصحیح قیمت تورم مثال

اکنون نگاه خواهیم کرد روی 3 روش برای اصلاح قیمت:

  1. ساخت یک متد نمونه در داخل کلاس برای اصلاح قیمت
  2. استفاده از روش کلاس برای اصلاح قیمت
  3. استفاده از یک تابع برای اصلاح قیمت

همه اینها عملیات مشابهی را انجام می دهند، فقط به روشی متفاوت.

روش ساخت یک متد نمونه در داخل کلاس برای اصلاح قیمت

در این مثال اول، یک متد instance در داخل کلاس ایجاد می کنیم house برای اصلاح قیمت تماس گرفت correctPriceMethod():

class house():

    company_name = "Awesome building company"

    inflation_coefficient = 1.08

    def __init__(self, address, state, Alarm, price):
        self.address = address
        self.state = state
        self.Alarm = Alarm
        self.price = price

    def correctPriceMethod(self):
        self.price = self.price * self.inflation_coefficient
اشعه خیلیexport

در این کد من متدی به نام ایجاد کردم correctPriceMethod():

    def correctPriceMethod(self):
        self.price = self.price * self.inflation_coefficient

به این ترتیب تمام خانه هایی که با کلاس خانه ساخته شده اند روشی برای به روز رسانی قیمت های خود خواهند داشت.

به عنوان مثال، فرض کنید یک آپارتمان با اطلاعات زیر داریم:

apartment1 = house(1234, "california", False , 300000)

apartment1.correctPriceMethod()

print(apartment1.price)

در خط زیر:

 apartment.correctPriceMethod():

این روش قیمت را از 300000 دلار به 324000 دلار به روز می کند تا تورم را منعکس کند.

در زیر دوباره همان کد وجود دارد، اما با دو آپارتمان دیگر برای نمایش دو روش دیگر برای به‌روزرسانی قیمت. بیایید روش اول را در اینجا بررسی کنیم:

class house():

    company_name = "Awesome building company"

    inflation_coefficient = 1.08

    def __init__(self, address, state, Alarm, price):
        self.address = address
        self.state = state
        self.Alarm = Alarm
        self.price = price

    def correctPriceMethod(self):
        self.price = self.price * self.inflation_coefficient
        
#----------------------------------------------------------------

apartment1 = house(1234, "california", False , 300000)
apartment2 = house(1234, "california", False , 300000)
apartment3Price = 300000

print(apartment1.price)

apartment1.correctPriceMethod()
print(apartment1.price)

>>> 300000
>>> 324000
2-1

من قیمت آپارتمان 1 را با correctPriceMethod.

بنابراین من قیمت را با روشی در یک نمونه کلاس به روز کردم.

روش استفاده از روش کلاس برای اصلاح قیمت

در این مثال، به جای استفاده از روش نمونه، از روش کلاسی برای اصلاح تورم برای به روز رسانی آپارتمان 2 استفاده می کنم.

به عبارت دیگر، به جای فراخوانی متد apartment1.correctPriceMethod()، من استفاده خواهم کرد house.correctPriceMethod(apartment2):

class house():

    company_name = "Awesome building company"

    inflation_coefficient = 1.08

    def __init__(self, address, state, Alarm, price):
        self.address = address
        self.state = state
        self.Alarm = Alarm
        self.price = price

    def correctPriceMethod(self):
        self.price = self.price * self.inflation_coefficient

#-----------------------------------------------------------

apartment1 = house(1234, "california", False , 300000)
apartment2 = house(1234, "california", False , 300000)
apartment3Price = 300000

apartment1.correctPriceMethod()

#-----------------------------------------------------------
print(apartment2.price)

house.correctPriceMethod(apartment2)
print(apartment2.price)

>>> 300000
>>> 324000
3-1

این بار به جای روش نمونه، قیمت را با روش کلاس آپدیت کردم.

به بیان دیگر، house.correctPriceMethod(apartment2) و apartment2.correctPriceMethod() یکسان هستند

اولی متد را از کلاس می گیرد، در حالی که دومی متد را از نمونه کلاس دریافت می کند.

روش استفاده از یک تابع برای اصلاح قیمت

بنابراین ما دیدیم که چگونه قیمت را با یک روش نمونه و یک متد کلاس به روز کنیم.

در این مثال نهایی، ما به سادگی از یک تابع برای به روز رسانی تورم استفاده می کنیم.

اکنون قیمت آپارتمان سوم را به روز می کنم، اما این بار با یک تابع:

def correctPricefunction(apartment):
    return apartment * 1.08

بیایید این را به کد اضافه کنیم:

class house():

    company_name = "Awesome building company"

    inflation_coefficient = 1.08

    def __init__(self, address, state, Alarm, price):
        self.address = address
        self.state = state
        self.Alarm = Alarm
        self.price = price

    def correctPriceMethod(self):
        self.price = self.price * self.inflation_coefficient

#-----------------------------------------------------------

apartment1 = house(1234, "california", False , 300000)
apartment2 = house(1234, "california", False , 300000)
apartment3Price = 300000

apartment1.correctPriceMethod()

#-----------------------------------------------------------

house.correctPriceMethod(apartment2)

#-----------------------------------------------------------

def correctPricefunction(apartment):
    return apartment * 1.08

print(apartment3Price)

apartment3Price = correctPricefunction(apartment3Price)
print(apartment3Price)

>>> 300000
>>> 324000
4

ما همین کار را فقط با قیمت آپارتمان3 انجام می دهیم – اما این بار از یک تابع استفاده می کنیم.

درست است، ما هم همین را داریم. هیچ تغییری وجود ندارد.

یک متد به سادگی یک تابع مرتبط با یک کلاس است، در حالی که یک تابع به تنهایی یک تابع است.

با استفاده از یک متد، تابعی را جداسازی می‌کنید که داده‌ها را از کلاس به جای داده‌های نه از کلاس تغییر می‌دهد.

در پایتون مواردی وجود دارد که بهتر است از تابعی استفاده شود که یک متد باشد.

از اینجا کجا برویم؟

این مقاله سطح برنامه نویسی شی گرا را بررسی می کند.

برای درک کامل آن، خوب است یک چیز را از دیدگاه های مختلف یاد بگیرید.

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

  1. می توانید با این دوره آموزشی YouTube از کانال freeCodeCamp وارد شوید و اطلاعات بیشتری کسب کنید:
آموزش برنامه نویسی شی گرا با پایتون
برنامه نویسی شی گرا یک مفهوم مهم در توسعه نرم افزار است. برنامه نویسی شی گرا (OOP) یک الگوی برنامه نویسی است که متکی است روی مفهوم کلاس ها و اشیا شما می توانید از این روش برنامه نویسی در بسیاری از زبان های برنامه نویسی از جمله Python که ما به تازگی منتشر کرده ایم استفاده کنید.
اوه

2. کد واقعی پشت 4 ستون اصلی OOP را در پایتون یاد بگیرید و بنویسید:

  • پلی مورفیسم
  • کپسوله سازی
  • وراثت
  • انتزاع – مفهوم – برداشت

3. پروژه های OOP را در پایتون و در یک زبان برنامه نویسی دیگر اعمال و انجام دهید.

4. پیشرفته تر: الگوهای اصلی طراحی نرم افزار را بیاموزید.

بسته بندی

در اینجا چیزی است که ما در این آموزش پوشش داده ایم:

  • چه کلاس هایی هستند
  • کلمه کلیدی خود چیست و چرا درک آن آسان است
  • متغیرهای کلاس چیست؟
  • تفاوت بین توابع و روش ها

شما همچنین در مورد برخی از بهترین روش ها برای دنبال کردن در برنامه نویسی شی گرا یاد گرفتید.

با تشکر از شما برای خواندن!