در این سخنرانی با کلاس ها، سازنده ها و وراثت در پایتون آشنا می شویم.
این مفاهیم در یک برنامه بزرگ که در آن نیاز به تعریف انواع مختلف است، واقعا مهم هستند.
کلاس
کلاس ها در برنامه نویسی ضروری هستند و مختص پایتون نیستند. بسیاری دیگر زبانهای برنامه نویسی از مفهوم کلاس ها حمایت می کند. ما از کلاس ها برای تعریف انواع داده های جدید استفاده می کنیم.
تا کنون، ما در مورد انواع داده های اساسی در پایتون مانند اعداد، رشته ها و بولی ها یاد گرفته ایم. اینها انواع داده های اولیه یا ساده در پایتون هستند. ما همچنین چند نوع داده پیچیده مانند لیست ها و فرهنگ لغت ها را دیده ایم.
در حالی که این انواع بسیار مفید هستند، همیشه نمی توان از آنها برای مدل سازی مفاهیم پیچیده استفاده کرد. به عنوان مثال، به ایده یک نقطه یا یک سبد خرید فکر کنید. سبد خرید یک لیست یا یک لیست نیست. این یک نوع داده متفاوت است. بنابراین میتوانیم از کلاسها برای تعریف انواع جدید برای مدلسازی مفاهیم واقعی استفاده کنیم.
حال بیایید یک نوع داده جدید به نام point تعریف کنیم. این نوع جدید همانطور که قبلا بررسی کردیم روش هایی خواهد داشت.
به این صورت این کار را انجام خواهید داد:
ما با تعریف یک کلاس با استفاده از کلمه کلیدی “class” شروع می کنیم و بلافاصله بعد از آن نام کلاس خود را می گذاریم.
class Point
اکنون، به قرارداد نامگذاری که من در اینجا استفاده کرده ام نگاه کنید. من در اینجا حرف اول را با حروف بزرگ نوشته ام، این همان چیزی است که ما آن را قرارداد نامگذاری پاسکال می نامیم. این قرارداد با قراردادی که برای نامگذاری متغیرها و توابع خود استفاده میکنیم متفاوت است و همیشه از حروف کوچک استفاده میکنیم و چندین کلمه را با استفاده از خط زیر جدا میکنیم. اما هنگام نامگذاری کلاسها، از خط زیر برای جدا کردن چند کلمه استفاده نمیکنیم، بلکه حرف اول هر کلمه را بزرگ مینویسیم.
پس از تعریف کلاس ما، از یک دو نقطه استفاده می شود که به این معنی است که اکنون یک بلوک تعریف شده است.
class Point:
def move (self):
در این بلوک می توانیم تمام توابع یا متدهایی را که متعلق به نقاط هستند تعریف کنیم. به عنوان مثال، ما می توانیم تابعی به نام "حرکت" برای جابجایی یک نقطه تعریف کنیم. توجه داشته باشید که به محض تایپ پرانتز باز، PyCharm به طور خودکار "self" را در اینجا اضافه می کند. این یک کلمه کلیدی خاص است و اجازه دهید به زودی به آن بازگردم. بیایید "حرکت" را در ترمینال چاپ کنیم.
print("move")
بیایید روش دیگری مانند "draw" تعریف کنیم و آن را در ترمینال چاپ کنیم.
def draw(self):
print("draw")
ما با تعریف کلاس "نقطه" خود به پایان رسیدیم. با این نوع جدید می توانیم اشیاء جدیدی ایجاد کنیم. یک کلاس به سادگی طرح یا الگوی ایجاد اشیایی را که نمونه های واقعی بر اساس آن طرح هستند، تعریف می کند. برای ایجاد یک شی، نام کلاس خود را تایپ می کنیم و آن را مانند یک تابع فراخوانی می کنیم. این یک شی جدید ایجاد می کند و سپس آن را برمی گرداند. سپس می توانیم آن شی را در یک متغیر ذخیره کنیم. بگذار نشانت دهم:
در اینجا نقطه 1 را تعریف کرده ایم که یک نقطه سه بعدی است. می بینید که ما می توانیم مختصات فردی را در ترمینال چاپ کنیم.
با این نقطه می توانیم از دو روش ترسیم و حرکت استفاده کنیم.
بنابراین برای جمع بندی، از کلاس ها برای تعریف انواع جدید استفاده می کنیم و این انواع می توانند متدهایی داشته باشند که در بدنه کلاس تعریف می کنیم. کلاس ها می توانند ویژگی هایی داشته باشند که ما می توانیم در هر جایی از برنامه هایمان تنظیم کنیم.
سازندگان
تا اینجا نحوه ایجاد انواع جدید با استفاده از کلاس ها را یاد گرفتیم. حالا یک مشکل کوچک در این اجرا وجود دارد. ما می توانیم یک شی نقطه ای بدون مختصات x یا y با استفاده از کلاس ها ایجاد کنیم و این ایده آل نیست. بگذار نشانت دهم.
بیایید قبل از تنظیم مختصات x یک نقطه ایجاد کنیم و آن را چاپ کنیم. اجرای برنامه ما منجر به خطای ویژگی مانند زیر می شود:
به این معنی که شی نقطه ای هیچ ویژگی به نام x ندارد. حال مشکل این است که می توان یک شی نقطه ای بدون مختصات x یا y داشت. این منطقی نیست زیرا هر زمان که در مورد یک نقطه صحبت می کنیم، باید بدانیم که آن نقطه در کجا قرار دارد. برای حل این مشکل از سازنده استفاده می کنیم. سازنده تابعی است که در زمان ایجاد یک شیء فراخوانی می شود.
در اینجا نحوه استفاده از سازنده است. ابتدا مقادیر مختصات x و y را در برنامه فوق پاس می کنیم.
point = Point(10, 20)
print(point.x)
حال باید یک متد خاص به این کلاس به نام سازنده اضافه کنیم. نحو آن به این صورت است:
def __init__(self, x, y):
init
مخفف عبارت Initialized است و این تابع یا روشی است که هنگام ایجاد یک شی نقطه جدید فراخوانی می شود. x و y بلافاصله بعد از آن اضافه می شوند self
برای اضافه کردن دو پارامتر اضافی
پس از آن باید x و y را به مقادیر پاس شده یعنی 10 و 20 نگاشت کنیم
self.x = x
self.y = y
ما با استفاده از self
برای ارجاع به شی فعلی و سپس ویژگی x را به آرگومان x که به تابع "x" ارسال می شود، تنظیم می کنیم. به این ترتیب با استفاده از init
روش، ما می توانیم اشیاء خود را مقداردهی اولیه کنیم. از این روش به عنوان سازنده یاد می شود. بیایید برنامه خود را اجرا کنیم.
حالا می توانیم مختصات x و y را بعدا تغییر دهیم. بیایید مختصات x را به روز کنیم:
point = Point(10, 20)
point.x = 11
print(point.x)
اکنون مختصات x به مقدار 11 به روز می شود.
ورزش
در اینجا یک تمرین جالب برای شما آورده شده است.
از شما می خواهم یک نوع جدید به نام شخص تعریف کنید. این اشیاء "Person" باید دارای "name
” ویژگی و همچنین یک ”talk()
" روش.
این یک کار ساده است و نباید بیش از چند دقیقه طول بکشد.
راه حل
با تعریف کلاس "Person" به این صورت شروع کنید:
class Person:
self.name = name
سازنده را بعداً تعریف می کنیم. اکنون میتوانیم شی «Person» را ایجاد کنیم. اسمش را بگذاریم جان
john = Person("John Smith")
print(john.name)
john.talk()
حالا به قسمت اول کد بروید و یک سازنده ایجاد کنید.
def __init__(self, name):
کد نهایی به شکل زیر خواهد بود:
همچنین می توانید از رشته های قالب بندی شده و مفاهیم دیگر در ارتباط با کلاس ها و سازنده ها استفاده کنید.
وراثت
وراثت یکی دیگر از مفاهیم مرتبط با کلاس ها است که به شما امکان استفاده مجدد از یک کد را می دهد.
این قطعه کد را در نظر بگیرید.
class Dog:
def walk(self):
print("walk")
ما یک کلاس "Dog" با روش "walk" ایجاد کرده ایم. در این روش، ما به سادگی پیام پیاده روی را در ترمینال چاپ می کنیم. فرض کنید، در یک برنامه واقعی، 10 خط کد به جای یک خط در اینجا وجود دارد. در آینده، اگر کلاس دیگری برای داشتن متد “walk” مورد نیاز باشد، باید تمام آن کد را تکرار کنیم. این ایده آل نیست.
در برنامه نویسی، ما یک اصل به نام DRY داریم که مخفف کلمه تکرار نشدن است. فرض کنید در آینده، مشکلی را در روش "پیاده روی" خود کشف می کنیم و اگر این روش را در بسیاری از جاهای دیگر تکرار یا تکرار کرده باشیم، باید برگردیم و آن مشکل را در هر جایی که این روش را تکرار کرده ایم برطرف کنیم. کد پس به همین دلیل است که در برنامه نویسی نباید چیزی را دو بار تعریف کنیم.
روشهای مختلفی برای رفع این مشکل وجود دارد، اما در اینجا میخواهیم روشی را یاد بگیریم که برای مبتدیان آسانتر است و به آن وراثت میگویند. در این صورت، یک کلاس دیگر “mammal” ایجاد می کنیم و ویژگی “walk” خود را در آن کلاس تعریف می کنیم.
class Mammal:
def walk(self):
print("walk")
پس از تعریف کلاس "Mammal" خود، میتوانیم از وراثت برای انتقال ویژگیها به این صورت استفاده کنیم:
هر دو کلاس سگ و گربه تمام متدهای کلاس تعریف شده در کلاس والد خود را به ارث می برند. اکنون میتوانیم روشهای مخصوص سگها را مانند این اضافه کنیم:
class Dog:
def bark(self):
print("bark")
بسته شدن!
این همه در مورد کلاس ها، سازنده ها و استفاده مجدد از کد در کلاس هایی با مفاهیم وراثت بود. اکنون به پایان سریال خود نزدیک می شویم. تا این مرحله، شما باید بتوانید کدهای خوب، خوانا و مختصر در پایتون تولید کنید.
مفهوم ماژول ها و پکیج ها را در سخنرانی بعدی خواهیم دید.
پاسخ دهید