recent
أخبار ساخنة

الوراثة و أشكالها في لغة بايثون 24

AM VIIP
الصفحة الرئيسية
الوراثة و أشكالها في لغة بايثون 23

الوراثة inheritance في بايثون

الوراثة ( inheritance ) تعني أن كلاس يورث كلاس آخر يأخذ جميع الميثود في الكلاس الآخر مثلاً نريد عمل كلاس جديد و يورّث الكلاس في مثالنا السابق.

إنَّ كلمة وراثة تعني تضمين محتوى كلاس في كلاس آخر في بايثون, الكلاس يمكنه أن يرث من كلاس آخر حتى يحصل على الدوال و المتغيرات الموجودة فيه. إذاً فكرة الوراثة بسيطة لكن فائدتها قوية جداً. فمثلاً إذا كنت تريد إنشاء كلاس جديد و لاحظت أنه يوجد كلاس جاهز يحتوي على كودات قد تفيدك يمكنك استغلالها بدل كتابتها من الصفر, أي يمكنك جعل الكلاس الذي قمت بتعريفه يرث هذا الكلاس, و بعدها يمكنك إستخدام جميع المتغيرات و الدوال التي ورثها الكلاس الجديد من الكلاس الجاهز.

الكلاس الذي يرِث من كلاس آخر يسمى الكلاس الإبن و يسمى أيضاً Subclass و يقال له أيضاً ( Derived Class, Extended Class أو Child Class ) و الشائع أكثر يقال إنه ابن Child و إنما الكلاس الذي يورّث ما به لكلاس آخر يتم تسميته بالكلاس الأب و يسمى Superclass و يقال له ( Base Class أو Parent Class ).

إن الوراثة inheritance كما هو الحال المتعارف عليه في ارض الواقع أن يرث الإبن من أبيه بعض الصفات او من أمه بعض الصفات و في نفس الأمر لدينا في البرمجة الكائنية object oriented programming في مفهوم الوراثة و هو أن يرث كلاس من كلاس آخر بحيث أن الكلاس الوارث يسمى الإبن و الكلاس المورث يسمى الأب بحيث يستطيع الإبن الوصول لكافة الدوال و المتغيرات الموجودة في الكلاس الأب و إعادة إستخدامها مرة أخرى.

و نستفيد من الوراثه هي أن نختصر الكود فبدلاً من إعادة بناء الدالة مرة أُخرى إذا كانت الدالة موجودة في الكلاس الأب نستطيع إعادة إستخدامها مرة أُخرى بدلاً من بناءها و إستهلاك الذاكرة و إطالة الكود بحيث يكون البرنامج منظم و اجمل.

الشكل العام للوراثة Syntax

class BaseClass:
    Body class
class الكلاس المشتق(BaseClass):
        جسم الكلاس المشتق

 

إنشاء كلاس أب parent class في بايثون

يمكن لأي كلاس بأن يكون أب ( parent ) فإن بناء الجملة هو نفسه كإنشاء أي كلاس آخر.

class Info:
    def __init__ (self, name = "Muhammad Alush", age = 28):
        self.name = name
        self.age = age
    def my_info (self,data = "My Info"):
        print ("I am Programmer")
        print (data)
c = Info ("Muhammad", "26")
c.my_info ("data : ")
print (c.name
print (c.age)

 

إنشاء كلاس ابن child class في بايثون

لإنشاء كلاس إبن ترث الدالة من كلاس آخر, يجب إرسال الكلاس الرئيسي كـ باراميتر Parameter عند إنشاء كلاس فرعي.

class another_user(user):
    pass

سوف يكون للكلاس الذي يسمى user نفس الخصائص و الأساليب لدى another_user و يتم إستخدام كلمة pass عندما لا نريد إضافة أي دوال أو خصائص إلى الكلاس.

 

أشكال الوراثة في بايثون

في بايثون يوجد 4 أشكال للوراثة وهي:

  1. وراثة فردية Single inheritance و هي أن كلاس يرث من كلاس واحد فقط.
  2. وراثة متتالية Multi level inheritance و تعني بأن كلاس يرث من كلاس واحد و هذا الكلاس كان في الأصل يرث من كلاس آخر.
  3. وراثة متعددة Multiple inheritance تعني أن الكلاس يرث من أكثر من كلاس.
  4. وراثة هرمية Hierarchical inheritance تعني أن الكلاس موروث من قبل أكثر من كلاس.

 

مثال 1

سوف نكتب كلاسين وهما Info و Info2 و الكلاس الجديد Info2 يرث جميع ما في الكلاس Info.

class Info2 (Info):
   def mydata (self):
      print ("hello man")
c = Info2()
print (c.age)
print (c.name)
c.my_info()
c.mydata()

أنشأنا كلاس ابن وهو Info2 و قد ورث هذا الإبن من الكلاس الأب Info, و في داخل هذا الكلاس توجد دالة وهي mydata, ثم أنشأنا كائن c و تم استدعاء جميع الدوال في الكائن c.

إذا عملنا run سوف نحصل على النتيجة التالية

21
amviip
hello world man
my data
amviip
hello man

مثال 2

أنشئ كلاس class بإسم Cs مع كتابة خصائص الإسم الأول و الإسم الأخير في بايثون, إستخدم طريقة printname .

class Cs:
    def __init__(self, fname, lname):
        self.firstname = fname
        self.lastname = lname
def printname(self):
    print(self.firstname, self.lastname)

إستخدم كلاس Cs لإنشاء كائن ثم قم بتنفيذ طباعة الإسم.

x = Cs("Saja", "Osman")
x.printname()

و انشئ كلاس بإسم الطالب التي سوف يرث الخصائص و الأساليب من الكلاس Cs.

class Student(Cs):
    pass
 

الوراثة الفردية في بايثون

الوراثة الفردية ( Single inheritance ) عندما ترث فئة فردية من أب واحد فقط أو يرث الكلاس من كلاس واحد فهذا يُسمى وراثة أو ميراث فردي.

single Inheritance python

 

مثال 1

الملف الأول A.py

class A:
    x = 15
    def print_msg(self):
        print('Hello from class A')

قمنا بإنشاء كلاس إسمه A و في داخل هذا الكلاس يوجد متغير x و قيمته هي 15 و يوجد دالة إسمها print_msg و لهذه الدالة طباعة مهمة محددة.

الملف الثاني B.py

from A import A
class B(A):
    y = 25

لقد قمنا بتضمين أو إستدعاء الكلاس A الموجود في الملف A.py من أجل أن نستطيع الوراثة منه و أنشأنا كلاس إسمه B و يرث هذا الكلاس من A و يحتوي هذا الكلاس على متغير y قيمته 25.

الملف الثالث Test.py

from B import B
b = B()
print('y:', b.y)
print('x:', b.x)
b.print_msg()

قمنا بإستدعاء الكلاس B من الملف B.py حتى نستطيع إنشاء كائن من هذا الكلاس, و أنشأنا الكائن b من الكلاس B و قمنا بطباعة قيمة المتغير y الموجود في الكائن b الذي عرّفناه في الكلاس B, و من ثم طبعنا قيمة المتغير x الموجود في الكائن b الذي ورثه من الكلاس B من الكلاس A.

ثم إستدعينا الدالة print_msg() التي توجد في الكائن b وورثها الكلاس B من A.

عند التشغيل سنحصل على النتيجة

y: 25
x: 15
Hello from class A

مثال 2

سوف نقوم بإنشاء ملفين الأول هو الأب ونسميه main. و الثاني هو الإبن و نسميه index.

الملف الأول main

#file main.py
class Human:
    '''this class for human'''
    skin_color = 'black'
    hair_color = 'black'
    eye_color  = 'blue'
    def print_skin_color(self):
        return "your skin color is {}".format(self.skin_color)
    def print_hair_color(self):
        return f"my hair color is {self.hair_color}"
    def print_eye_color(self):
        return f"my eye color {self.eye_color}"

أنشأنا كلاس بإسم Human و هو الكلاس الأب, ثم أنشأنا له عدة خصائص أو صفات و هي لون البشرة و لون الشعر و لون العيون. ثم أعطيناه بعض الوظائف و هي طباعة لون البشرة print_skin_color و هذه الميثود تقوم بإرجاع لون البشرة و نسقنا العملية عبر إستخدام format. و الوظيفة الثانية هي طباعة لون الشعر و الوظيفة الثالثة طباعة لون العينين.

الملف الثاني index

#file index.py
from main import Human
class Person(Human):
    pass
app = Person()
result = app.print_eye_color()
print(result)

كتبنا from من أجل إستدعاء المكتبة أي الملف الأب main إجلب لي الكلاس Human ثم أنشانا كلاس الإبن بإسم Person و توريثه من الكلاس الأب Human و وضعنا pass من أجل عدم إضافة أي شيئ له. بعدها نعتبر أن الأب قد مات و أنشانا كائن app و عيينا له Person و أنشانا متغير result بعدها إستطاع الإبن الوصول للصفة التي ورثّها له الأب و هي print_eye_color و نفس الأمر سيستطيع الوصول لكل شيئ في الأب, ثم طبعنا المُتغير result. عندما نقوم بتشغيل هذا الكود سنلاحظ النتيجة الآتية و هي

my eye color blue

 

الوراثة المتتالية في بايثون

الوراثة المتتالية ( Multi level inheritance ) تعني عندما ترث فئة من فئات متعددة أو بمعنى أصح أن يرث الكلاس من أكثر من كلاس.

Multilevel inheritance python

 

مثال 1

class Base(object): 
    #Constructor
	def __init__(self, name): 
		self.name = name 
    #Name
	def Name(self): 
		return self.name  
class Child(Base): 
	#Constructor 
	def __init__(self, name, age): 
		Base.__init__(self, name) 
		self.age = age 
    #age
	def Age(self): 
		return self.age 
class GrandChild(Child): 
	#Constructor 
	def __init__(self, name, age, address): 
		Child.__init__(self, name, age) 
		self.address = address 
    #address
	def Address(self): 
		return self.address		 
g = GrandChild("Saja", 27, "Sudan") 
print(g.Name(), g.Age(), g.Address())

تم إنشاء كلاس جد و هو Base و يتضمن الأسم name و كلاس أب بإسم Chile و تضمن هذا الكلاس العمر age و الكلاس الأخير هو الحفيد و يرث هذا الحفيد من أبيه و جده الإسم و العمر إضافةً على ذلك لديه صفه العنوان, ثم قُمنا بطباعة الحفيد و كان يملك ثلاث خواص أحدها من أبيه و الأُخرى من جده و الأخيره هي به. و عند تنفيذ الكود السابق

Saja 27 Sudan

مثال 2

الملف الاول A.py

class A:
    def print_a(self):
        print('Hello from class A')

قمنا بتعريف كلاس A و يحتوي هذا الكلاس على دالة print_a().

الملف الثاني B.py

from A import A
class B(A):
    def print_b(self):
        print('Hello from class B')

قمنا بإستدعاء أو تضمين الكلاس A الموجود في الملف A.py حتى نستطيع الوراثة منه, و أنشأنا كلاس B يرث من الكلاس A و أنشأنا دالة print_b().

الملف الثالث C.py

from B import B
class C(B):
    def print_c(self):
        print('Hello from class C')

قمنا بتضمين الكلاس B الموجود في الملف B.py و أنشأنا كلاس جديد وهو C و أورثنا هذا الكلاس الجديد من B و أنشأنا دالة print_c.

الملف الرابع Test.py

from C import C
c = C()
c.print_a()
c.print_b()
c.print_c()

هنا ضمننا الكلاس C الموجود في الملف C.py و أنشأنا كائن c من الكلاس C و من ثم قمنا بإستدعاء جميع الدوال الموجودة في الكائن c.

عند تشغيل الكود سنحصل على النتيحة

Hello from class A
Hello from class B
Hello from class C

الوراثة المتعددة في بايثون

الوراثة المتعددة ( Multiple inheritance ) تعني عندما يكون لدينا عدة أصناف مثل جد و أب و حفيد. يعني أن الكلاس سوف يرث من أكثر من كلاس.

multiple Inheritance python

مثال 1

class Saja(object): 
	def __init__(self): 
		self.str1 = "Curious"
		print("Saja") 
class Muhammad(object): 
	def __init__(self): 
		self.str2 = "Crazy"		
		print("Muhammad") 
class Derive(Saja, Muhammad): 
	def __init__(self): 
		Saja.__init__(self) 
		Muhammad.__init__(self) 
		print("Derive") 
	def printStrs(self): 
		print(self.str1, self.str2) 
ob = Derive() 
ob.printStrs()

أنشأنا كلاس أول و هو Saja و أضفنا __init__ من أجل إضافة خواص لهذا الكلاس و أضفنا له الخاصية Curious أي أنه فضولي ثم طلبنا طباعة الكلاس عن طريق إستدعاء إسمه, و أنشأنا كلاس آخر وهو Muhammad و أيضاً أضفنا له خاصية أنه مجنون Crazy و بعد ذلك قُمنا بإشتقاق كلاس إبن يَرِث من الأبوين Saja و Muhammad. عندما نقوم بتشغيل هذا الكود سنلاحظ النتيجة الآتية و هي:

Saja
Muhammad
Derive
Curious Crazy

كما لاحظنا طبع لنا إسم الكلاس الأول و يليه بسطر جديد إسم الكلاس الثاني و هم الأبوين و أسفلهم طبع لنا الإبن و الصفات التي أخذها من الأبوين و هما الفضولية و الجنون.

مثال 2

الملف الأول A.py

class A:
    def print_a(self):
        print('Hello from class A')

أنشأنا كلاس A ووضعنا دالة و هي print_a.

الملف الثاني B.py

class B:
    def print_b(self):
        print('Hello from class B')

أنشأنا كلاس B و في هذا الكلاس دالة print_b.

الملف الثالث C.py

from A import A
from B import B
class C(A, B):
    def print_c(self):
        print('Hello from class C')

قمنا بتضمين الكلاس A الموجود في الملف A.py و ضمننا أيضاً الكلاس B الموجود في الملف B.py, و أنشأنا كلاس C يرث من الكلاسين A و B و توجد دالة print_c.

الملف الرابع Test.py

from C import C
c = C()
c.print_a()
c.print_b()
c.print_c()

قمنا بتضمين الكلاس C الموجود في الملف C.py ثم أنشأنا كائن c من الكلاس C ثم ثمنا بإستدعاء جميع الدوال الموجودة في الكائن c.

عند تشغيل الكود سنحصل على النتيجة.

Hello from class A
Hello from class B
Hello from class C

مثال تطبيقي الوراثة الهرمية بايثون

الوراثة الهرمية ( Hierarchical inheritance ) يعني إنشاء اكثر من فئة من قاعدة واحدة أو بمعنى أصَح أن هذا الكلاس موروث من أكثر من كلاس.

Hierarchical inheritance python

مثال 1

#الكلاس الأساسي
class MyWebsite:
    def programmer(self, name):
        self.name = name
        print(f'{self.name} Is Programming')
#كلاس فرعي1
class MuhammadAlush(MyWebsite):
    pass
#كلاس فرعي2
class AhmedAmviip(MyWebsite):
    pass
data = MuhammadAlush()
data.programmer("MuhammadAlush")
ahmed = AhmedAmviip()
ahmed.programmer("AhmedAmviip")
#لا توجد أي علاقة بين الكلاس الفرعي1 و الكلاس الفرعي2

يوجد لدينا كلاس أساسي و هو MyWebsite و به داله progammer و كلاسين فرعيات و هما MuhammadAlush و الكلاس الآخر AhmedAmviip لكن كما نرى لا توجد أي علاقة بين الكلاسين الفرعيات و قد ورثوا من الأب أنهم مبرمجين. و عند تشغيل الكود السابق ستكون نتيجة هي

MuhammadAlush Is Programming
AhmedAmviip Is Programming

مثال 2

الملف الأول A.py

class A:
    def print_a(self):
        print('Hello from class A')

أنشأنا كلاس A و في داخل الكلاس توجد دالة وهي print_a.

الملف الثاني B.py

from A import A
class B(A):
    def print_b(self):
        print('Hello from class B')

قمنا بتضمين الكلاس A من الملف A.py و أنشأنا كلاس B و ورث من الكلاس A و قمنا بإنشاء دالة print_b.

الملف الثالث C.py

from A import A
class C(A):
    def print_c(self):
        print('Hello from class C')

قمنا بتضمين الكلاس A الموجود في الملف A.py و أنشأنا كلاس C يرث من الكلاس A و يحتوي على دالة print_c.

الملف الرابع Test.py

from B import B
from C import C
c = C()
c.print_a()
c.print_c()
b = B()
b.print_a()
b.print_b()

قمنا بتضمين الكلاس B الموجود في الملف B.py و الكلاس C الموجود في الملف C.py و أنشأنا كائن c من الكلاس C و استدعاء جميع الدوال الموجودة فيه, ثم أنشأنا كائن b من الكلاس B و إستدعاء جميع الدوال الموجودة فيه.

عند تشغيل الكود ستكون النتيجة

Hello from class A
Hello from class C
Hello from class A
Hello from class B

 

الوراثة الهجينة (Hybrid inheritance)

يكون هذا النوع مزيج من اكثر من نوع من انواع الوراثة

Hybrid inheritance python

مثال 1

class AdminWebsite:
	def func1(self):
		print("This function is Main.")
class MuhammedAlush(AdminWebsite):
	def func2(self):
		print("This function is MuhammadAlush. ")
class AhmedAmviip(AdminWebsite):
	def func3(self):
		print("This function is AhmedAmviip.")
class SajaAlsadig(MuhammedAlush, AdminWebsite):
	def func4(self):
		print("This function is SajaAlsadig.")
# Driver's code
object = SajaAlsadig()
object.func1()
object.func2()

و عند تشغيل الكود السابق

This function is Main.
This function is MuhammadAlush.

عندما يقوم كلاس بعملية وراثة اكثر من كلاس فإنه يوجد إحتمال كبير جداً أن يرِث خصائص و دوال لديها نفس الإسم, و بالتالي سوف يحدث تضارب في هذه الأسماء, كونك المبرمج عليك معرفة أن التضارب في الأسماء لا يسبب أي خطأ في الكود عند تشغيله و لكنه قد يؤدي لحدوث خطأ منطقي في النتيجة المرجو الحصول عليها.

و في حال كنت تريد إنشاء كلاس و ترغب في ضمان عدم حدوث أية مشاكل في تضارب الأسماء عند وراثة هذا الكلاس, عندها يمكنك إعتماد مبدأ إخفاء البيانات ( Data Hiding ) عند تسمية المتغيرات و الدوال, و إن الفكرة من إخفاء البيانات هي جعل المبرمج قادراً على وضع نفس أسماء المتغيرات و الدوال في الكلاس الأب و الإبن مع الضمان في عدم حدوث أي تضارب. و يمكنك ببساطة وضع الرمز __ في بداية إسم المتغير أو إسم الدالة لتصبح قادراً على إستخدام نفس الإسم في الكلاس الذي يرث منهم و حينها سوف يتولى مفسّر بايثون التفريق بين الأشياء الموجودة في الكلاسين الأب و الإبن.

google-playkhamsatmostaqltradent