Professional Documents
Culture Documents
მრავლობითი მემკვიდრეობითობა
gachechiladze_lela@yahoo.com
რას გულისხმობს მრავლობითი
მემკვიდრეობითობა?
როგორც ცნობილია, ობიექტზე ორიენტირებული დაპროგრამების ერთ-ერთ
ფუნდამენტურ პრინციპს მემკვიდრეობითობა წარმოადგენს.
პითონში შესაძლებელია არა მხოლოდ მარტივი მემკვიდრეობითობის, არამედ
მრავლობითი მემკვიდრეობითობის განხორციელებაც, რაც იმ ფაქტს გულისხმობს,
რომ შვილობილ კლასს შესაძლებლობა აქვს ფუნქციონალი მიიღოს არა მხოლოდ
ერთი, არამედ რამდენიმე მშობელი კლასისგან. აღნიშნულის საილუსტრაციოდ
შემდეგი პროგრამული კოდი განვიხილოთ:
class Doctor:
def can_cure(self):
print("მე ვარ ექიმი და ვმკურნალობ პაციენტებს.")
class Builder:
def can_build(self):
print("მე ვარ მშენებელი და ვაშენებ სახლებს.") შედეგები:
gachechiladze_lela@yahoo.com 2
მე-2 სლაიდზე წარმოდგენილი კოდის
ანალიზი
წინა (მე-2) სლაიდზე წარმოდგენილ პროგრამულ კოდში ჩვენ შევქმენით სამი
კლასი: Doctor, Builder და Person კლასები. ამ უკანასკნელმა (Person ) კლასმა მემ-
კვიდრეობით მიიღო წინა ორი (Doctor დაBuilder) კლასების, როგორც მისი მშობელი
კლასების, ფუნქციონალი - მეთოდები: can_cure() და can_build(). რაც ითვალისწი-
ნებს იმ ფაქტს, რომ Person კლასის ობიექტს შეუძლია მიმართოს (გამოიყენოს)
თავის მშობელ კლასებში განსაზღვრულ ზემოაღნიშნულ მეთოდებს.
ამგვარად, მემკვიდრეობით კლასებს შეუძლიათ გამოიყენონ მშობელი კლასების
მეთოდები. მაგრამ, თუ რამდენიმე მშობელს ერთნაირი მეთოდები აქვს? რომელ
მეთოდს გამოიყენებს ამ შემთხვევაში მემკვიდრე კლასი?
gachechiladze_lela@yahoo.com 3
მრავლობითი მემკვიდრეობითობის რეალიზება
Method Resolution Order / MRO
განვიხილოთ შემდეგი პროგრამული კოდი:
class A:
def hi(self):
print("Class A")
class B(A):
def hi(self): შედეგი:
print("Class B")
class C(A):
def hi(self):
print("Class C")
class D(B, C):
pass
d = D()
d.hi()
აღნიშნულ შემთხვევას რომბისებური მემკვიდრეობითობა (diamond problem)
ეწოდება და ის მეთოდების გამოძახების (რეალიზების) რიგის გათვალისწინებით
წყდება. პითონში აღნიშნული რიგის განსაზღვრის მიზნით სიგანეში ძებნის ალგო-
რითმი გამოიყენება, რაც ნიშნავს, რომ ინტერპრეტატორი hi მეთოდს ჯერ D კლასში
ეძებს, და რადგან ის არ მოიცავს აღნიშნულ მეთოდს, ძებნას აგრძელებს ჯერ B
კლასში (რამეთუ, ის მემკვიდრე კლასების სიაში პირველი - მარცხნივ დგას) და შემ-
დეგ C კლასში (იმ შემთხვევაში, თუ B კლასი ამ მეთოდს არ მოიცავს) და სულ
ბოლოს - A კლასში. gachechiladze_lela@yahoo.com 4
მეთოდი mro()
შედეგები:
gachechiladze_lela@yahoo.com 5
მე-4 სლაიდზე წარმოდგენილი კოდის მოდიფიკაცია
class B(A):
def hi(self):
print("Class B")
class C(A):
def hi(self):
print("Class C")
d = D()
d.call_hi()
gachechiladze_lela@yahoo.com 6
კონფლიქტური სიტუაციები
დავუშვათ, მე-2 სლაიდზე წარმოდგენილ კოდში Person კლასსაც გააჩნია მეთო-
დი სახელწოდებით can_build(). ამ შემთხვევაში, თუ ჩვენ შვილობილი (Person )
კლასის ობიექტით მივმართავთ აღნიშნულ მეთოდს, ცხადია, ის თავის კლასში გან-
საზღვრულ მეთოდს გამოიძახებს და არა Builder კლასში განსაზღვრულ მეთოდს.
კერძოდ:
class Doctor:
def can_cure(self):
print("მე ვარ ექიმი და ვმკურნალობ პაციენტებს.")
class Builder:
def can_build(self):
print("მე ვარ მშენებელი და ვაშენებ სახლებს.")
p=Person()
p.can_build()
gachechiladze_lela@yahoo.com 7
კონფლიქტური სიტუაციები (გაგრძელება)
ახლა დავუშვათ, რომ can_biuld() მეთოდი Doctor კლასსაც გააჩნია და Builder
კლასსაც, ხოლო Person კლასს - არა. ანუ, გვაქვს შემდეგი სიტუაცია:
class Doctor:
def can_cure(self):
print("მე ვარ ექიმი და ვმკურნალობ პაციენტებს.")
def can_build(self):
print("მე ვარ ექიმი და მეც ვაშენებ სახლებს, თუმცა, არც ისე კარგად :(")
class Builder:
def can_build(self):
print("მე ვარ მშენებელი და ვაშენებ სახლებს.")
gachechiladze_lela@yahoo.com 8
კონფლიქტური სიტუაციები (გაგრძელება)
თუ წინა (მე-8) სლაიდზე წარმოდგენილ კოდში მშობელი კლასების ჩამო-
ნათვალში გადავაადგილებთ Doctor და Builder კლასებს, შემდეგ სურათს მივიღებთ:
class Doctor:
def can_cure(self):
print("მე ვარ ექიმი და ვმკურნალობ პაციენტებს.")
def can_build(self):
print("მე ვარ ექიმი და მეც ვაშენებ სახლებს, თუმცა, არც ისე კარგად :(")
class Builder:
def can_build(self):
print("მე ვარ მშენებელი და ვაშენებ სახლებს.")
gachechiladze_lela@yahoo.com 9
მეთოდი super()
წინა (მე-9) სლაიდზე წარმოდგენილ კოდში სამივე კლასში დავამატოთ ერთი და
იმავე სახელის მქონე მეთოდი graduate() და შვილობილ კლასში შევეცადოთ super()
მეთოდის გამოყენებით გამოვიძახოთ ეს მეთოდი. საინტერესოა, რომელი სუპერ-
კლასის მეთოდი იმუშავებს - Doctor თუ Builder კლასის?
class Builder:
def graduate(self):
print("მე გავხდი მშენებელი.")
gachechiladze_lela@yahoo.com 10
მეთოდი super()
თუ წინა (მე-10) სლაიდზე წარმოდგენილ კოდში მემკვიდრე კლასის graduate()
მეთოდში დავამატებთ ბრძანებას: Builder.graduate(self), რომელსაც წინ უსწრებს
ბრძანება: super().graduate(), მაშინ ცხადია, ჩვენ ორივე მშობელ კლასში განსაზღვ-
რულ მეთოდს გამოვიძახებთ:
class Doctor: შედეგები:
def graduate(self):
print("მე გავხდი ექიმი.")
class Builder:
def graduate(self):
print("მე გავხდი მშენებელი.")
gachechiladze_lela@yahoo.com 11
__init__ მეთოდი და მრავლობითი მემკვიდრეობითობა
მე-11 სლაიდზე წარმოდგენილ პროგრამულ კოდში ყველა კლასში ჩავამატოთ
პარამეტრებიანი კონსტრუქტორი (__init__) მეთოდი და ვნახოთ, როგორ ხდება
მათი გამოძახება მემკვიდრე კლასიდან.
class Doctor:
def __init__(self, degree):
self.degree=degree
class Builder:
def __init__(self, rank):
self.rank=rank
def graduate(self):
print("მე გავხდი მშენებელი.")
p=Person("Spec", 5)
p.graduate() gachechiladze_lela@yahoo.com 12
გისურვებთ წარმატებულ სწავლას!
gachechiladze_lela@yahoo.com 13