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

آموزش Inheritance، کلاس والد، کلاس فرزند و super در Python

در درس‌های قبلی با کلاس، Object، متد __init__ و Methodها آشنا شدیم. حالا به یکی از مفاهیم مهم برنامه‌نویسی شی‌ءگرا یعنی Inheritance یا وراثت می‌رسیم.

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

وراثت چیست؟

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

به کلاس اصلی معمولاً Parent Class یا کلاس والد گفته می‌شود.

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

به زبان ساده:

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

یک مثال ساده از وراثت

ابتدا یک کلاس والد به نام Person ایجاد می‌کنیم:

class Person:

    def introduce(self):
        print("I am a person")

حالا یک کلاس فرزند به نام Student ایجاد می‌کنیم:

class Student(Person):
    pass

در اینجا Student از Person ارث‌بری می‌کند.

بنابراین می‌توانیم متد introduce() را از طریق Object کلاس Student اجرا کنیم.

student1 = Student()

student1.introduce()

خروجی:

I am a person

مزیت وراثت چیست؟

یکی از مهم‌ترین مزایای وراثت، استفاده مجدد از کد است.

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

اضافه کردن ویژگی جدید به کلاس فرزند

کلاس فرزند فقط می‌تواند از کلاس والد استفاده کند؛ بلکه می‌تواند ویژگی‌ها و متدهای جدید خودش را نیز داشته باشد.

class Person:

    def introduce(self):
        print("I am a person")


class Student(Person):

    def study(self):
        print("I am studying")


student1 = Student()

student1.introduce()
student1.study()

خروجی:

I am a person
I am studying

در این مثال:

استفاده از __init__ در وراثت

کلاس والد نیز می‌تواند __init__ داشته باشد.

class Person:

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


class Student(Person):
    pass


student1 = Student("Ali")

print(student1.name)

خروجی:

Ali

چون Student از Person ارث‌بری می‌کند، می‌تواند از __init__ کلاس والد استفاده کند.

وقتی کلاس فرزند __init__ داشته باشد

حالا فرض کنیم کلاس فرزند خودش نیز __init__ داشته باشد.

class Person:

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


class Student(Person):

    def __init__(self, name, grade):
        self.name = name
        self.grade = grade


student1 = Student("Ali", 12)

print(student1.name)
print(student1.grade)

در این حالت __init__ کلاس فرزند اجرا می‌شود.

super() چیست؟

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

class Person:

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


class Student(Person):

    def __init__(self, name, grade):
        super().__init__(name)
        self.grade = grade


student1 = Student("Ali", 12)

print(student1.name)
print(student1.grade)

خروجی:

Ali
12
نکته:

دستور super().__init__(name) باعث می‌شود __init__ کلاس والد نیز اجرا شود.

یک مثال واقعی‌تر

فرض کنید یک سیستم ساده برای مدیریت افراد داریم. ابتدا کلاس والد Person را ایجاد می‌کنیم.

class Person:

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

    def show_info(self):
        print("Name:", self.name)
        print("Age:", self.age)

حالا کلاس Student را از آن ایجاد می‌کنیم:

class Student(Person):

    def __init__(self, name, age, grade):
        super().__init__(name, age)
        self.grade = grade

    def show_grade(self):
        print("Grade:", self.grade)


student1 = Student("Ali", 20, 12)

student1.show_info()
student1.show_grade()

خروجی:

Name: Ali
Age: 20
Grade: 12

در این مثال کلاس Student ویژگی‌های name و age را از کلاس Person دریافت کرده و ویژگی جدید grade را نیز به آن اضافه کرده است.

Override چیست؟

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

به این کار Method Overriding یا بازنویسی متد گفته می‌شود.

class Animal:

    def sound(self):
        print("Animal makes a sound")


class Dog(Animal):

    def sound(self):
        print("Dog says: Woof!")


dog1 = Dog()

dog1.sound()

خروجی:

Dog says: Woof!

در اینجا متد sound() در کلاس Dog بازنویسی شده است.

ساختار کلی وراثت

class Parent:

    def method1(self):
        print("Parent")


class Child(Parent):

    def method2(self):
        print("Child")


object1 = Child()

object1.method1()
object1.method2()

کلاس Child می‌تواند هم از method1() و هم از method2() استفاده کند.

تمرین

یک کلاس والد به نام Vehicle ایجاد کنید که ویژگی brand و متد show_brand() داشته باشد.

سپس یک کلاس فرزند به نام Car ایجاد کنید که از Vehicle ارث‌بری کند.

کلاس Car باید یک ویژگی جدید به نام color داشته باشد.

در نهایت یک Object از Car ایجاد کنید و برند و رنگ آن را نمایش دهید.

جمع‌بندی

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

درس بعدی: در درس بعدی با کپسوله‌سازی (Encapsulation) آشنا می‌شویم و یاد می‌گیریم چگونه دسترسی به داده‌ها و ویژگی‌های یک Object را بهتر مدیریت کنیم.