آموزش پایتون - وراثت

وراثت در پایتون چیست؟

وراثت یکی از مهم‌ترین ویژگی‌های زبان‌های برنامه‌نویسی شیءگرا مانند پایتون است. از وراثت برای به‌ارث بردن ویژگی‌ها و رفتارهای یک کلاس در کلاس دیگر استفاده می‌شود. کلاسی که از کلاس دیگری ارث‌بری می‌کند، کلاس فرزند نامیده می‌شود و کلاسی که ویژگی‌ها و رفتارهای آن به ارث برده می‌شوند، کلاس پایه یا کلاس والد نام دارد.

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

زمانی از وراثت استفاده می‌کنیم که بین یک کلاس جدید و یک کلاس موجود، رابطه «یک نوع از» (IS A) برقرار باشد. برای مثال، خودرو یک وسیله نقلیه است، اتوبوس یک وسیله نقلیه است و دوچرخه نیز یک وسیله نقلیه است. در این مثال، Vehicle کلاس والد است و car، bus و bike کلاس‌های فرزند هستند.

inheritance

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

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

نحو

نحو ایجاد یک کلاس والد در ادامه نشان داده شده است:

class ParentClassName:
   {class body}

ایجاد کلاس فرزند

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

نحو

نحو تعریف کلاس فرزند به شکل زیر است:

class SubClassName (ParentClass1[, ParentClass2, ...]):
   {sub class body}

انواع وراثت

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

  • وراثت تکی
  • وراثت چندگانه
  • وراثت چندسطحی
  • وراثت سلسله‌مراتبی
  • وراثت ترکیبی

types of inheritance

وراثت تکی در پایتون

این ساده‌ترین شکل وراثت است که در آن یک کلاس فرزند، ویژگی‌ها و متدها را تنها از یک کلاس والد به ارث می‌برد.

مثال

مثال زیر مفهوم وراثت تکی را در پایتون نشان می‌دهد:

# parent class
class Parent: 
   def parentMethod(self):
      print ("Calling parent method")

# child class
class Child(Parent): 
   def childMethod(self):
      print ("Calling child method")

# instance of child
c = Child()  
# calling method of child class
c.childMethod() 
# calling method of parent class
c.parentMethod() 

با اجرای کد بالا، نتیجه زیر چاپ می‌شود:

Calling child method
Calling parent method

وراثت چندگانه در پایتون

وراثت چندگانه در پایتون به شما امکان می‌دهد کلاسی را بر اساس بیش از یک کلاس والد ایجاد کنید. بنابراین، کلاس فرزند ویژگی‌ها و متدهای همه کلاس‌های والد را به ارث می‌برد. کلاس فرزند می‌تواند متدهای به‌ارث‌رسیده از هر یک از کلاس‌های والد را بازنویسی کند.

نحو

class parent1:
   #statements

class parent2:
   #statements

class child(parent1, parent2):
   #statements

مثال

کتابخانه استاندارد پایتون دارای تابع داخلی divmod() است که یک تاپل دو عضوی برمی‌گرداند. مقدار اول حاصل تقسیم دو آرگومان و مقدار دوم باقی‌مانده تقسیم دو عملوند است.

در این مثال تلاش می‌کنیم عملکرد تابع divmod() را شبیه‌سازی کنیم. دو کلاس به نام‌های division و modulus تعریف می‌کنیم و سپس کلاسی به نام div_mod می‌سازیم که از هر دوی آن‌ها ارث‌بری می‌کند.

class division:
   def __init__(self, a,b):
      self.n=a
      self.d=b
   def divide(self):
      return self.n/self.d
class modulus:
   def __init__(self, a,b):
      self.n=a
      self.d=b
   def mod_divide(self):
      return self.n%self.d

class div_mod(division,modulus):
   def __init__(self, a,b):
      self.n=a
      self.d=b
   def div_and_mod(self):
      divval=division.divide(self)
      modval=modulus.mod_divide(self)
      return (divval, modval)

کلاس فرزند متد جدیدی به نام div_and_mod() دارد که در داخل خود، متدهای divide() و mod_divide() را از کلاس‌های به‌ارث‌رسیده فراخوانی می‌کند تا حاصل تقسیم و باقی‌مانده را برگرداند.

x=div_mod(10,3)
print ("division:",x.divide())
print ("mod_division:",x.mod_divide())
print ("divmod:",x.div_and_mod())

خروجی

division: 3.3333333333333335
mod_division: 1
divmod: (3.3333333333333335, 1)

ترتیب حل متدها (MRO)

اصطلاح ترتیب حل متدها به وراثت چندگانه در پایتون مربوط می‌شود. در پایتون، وراثت می‌تواند در چندین سطح گسترش یابد. فرض کنید A والد B و B نیز والد C باشد. کلاس C می‌تواند متد به‌ارث‌رسیده را بازنویسی کند یا شیء ساخته‌شده از آن می‌تواند متد را همان‌طور که در کلاس والد تعریف شده است، فراخوانی کند. اما پایتون چگونه متد مناسب را برای فراخوانی پیدا می‌کند؟

هر کلاس در پایتون متد mro() را دارد که ترتیب سلسله‌مراتبی مورد استفاده پایتون برای پیدا کردن متدی را که باید فراخوانی شود، برمی‌گرداند. این ترتیب از پایین به بالای سلسله‌مراتب وراثت است.

در مثال قبلی، کلاس div_mod از کلاس‌های division و modulus ارث‌بری می‌کند. بنابراین، متد mro ترتیب زیر را برمی‌گرداند:

[<class '__main__.div_mod'>, <class '__main__.division'>, <class '__main__.modulus'>, <class 'object'>]

وراثت چندسطحی در پایتون

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

مثال

در مثال زیر، نحوه عملکرد وراثت چندسطحی را نشان می‌دهیم.

# parent class
class Universe: 
   def universeMethod(self):
      print ("I am in the Universe")

# child class
class Earth(Universe): 
   def earthMethod(self):
      print ("I am on Earth")

# another child class
class India(Earth): 
   def indianMethod(self):
      print ("I am in India")      

# creating instance 
person = India()  
# method calls
person.universeMethod() 
person.earthMethod() 
person.indianMethod() 

با اجرای کد بالا، نتیجه زیر تولید می‌شود:

I am in the Universe
I am on Earth
I am in India

وراثت سلسله‌مراتبی در پایتون

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

مثال

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

# parent class
class Manager: 
   def managerMethod(self):
      print ("I am the Manager")

# child class
class Employee1(Manager): 
   def employee1Method(self):
      print ("I am Employee one")

# second child class
class Employee2(Manager): 
   def employee2Method(self):
      print ("I am Employee two")      

# creating instances 
emp1 = Employee1()  
emp2 = Employee2()
# method calls
emp1.managerMethod() 
emp1.employee1Method()
emp2.managerMethod() 
emp2.employee2Method()  

با اجرای برنامه بالا، خروجی زیر را دریافت خواهید کرد:

I am the Manager
I am Employee one
I am the Manager
I am Employee two

وراثت ترکیبی در پایتون

ترکیب دو یا چند نوع وراثت را وراثت ترکیبی می‌نامند. برای مثال، این نوع وراثت می‌تواند ترکیبی از وراثت تکی و وراثت چندگانه باشد.

مثال

در این مثال، وراثت تکی و چندگانه را با هم ترکیب کرده‌ایم تا وراثت ترکیبی بین کلاس‌ها را ایجاد کنیم.

# parent class
class CEO: 
   def ceoMethod(self):
      print ("I am the CEO")

class Manager(CEO): 
   def managerMethod(self):
      print ("I am the Manager")

class Employee1(Manager): 
   def employee1Method(self):
      print ("I am Employee one")

class Employee2(Manager, CEO): 
   def employee2Method(self):
      print ("I am Employee two")      

# creating instances 
emp = Employee2()
# method calls
emp.managerMethod() 
emp.ceoMethod()
emp.employee2Method()

با اجرای برنامه بالا، نتیجه زیر نمایش داده می‌شود:

I am the Manager
I am the CEO
I am Employee two

تابع super()

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

مثال

در مثال زیر، یک کلاس والد ایجاد می‌کنیم و با استفاده از تابع super() به سازنده آن از داخل یک کلاس فرزند دسترسی پیدا می‌کنیم.

# parent class
class ParentDemo:
   def __init__(self, msg):
      self.message = msg

   def showMessage(self):
      print(self.message)

# child class
class ChildDemo(ParentDemo):
   def __init__(self, msg):
      # use of super function
      super().__init__(msg)  

# creating instance
obj = ChildDemo("Welcome to Tutorialspoint!!")
obj.showMessage()  

با اجرای برنامه بالا، نتیجه زیر نمایش داده می‌شود:

Welcome to Tutorialspoint!!

پیشرفت مطالعه: وضعیت خوانده‌شدن این درس فقط در همین مرورگر ذخیره می‌شود؛ بدون نیاز به حساب کاربری.