You are on page 1of 15

XII ლექცია

პოლიმორფიზმი

gachechiladze_lela@yahoo.com
რა შემთხვევაში მივმართავთ
პოლიმორფიზმს?
სანამ უშუალოდ განვმარტავდეთ, თუ რას წარმოაგდენს პოლიმორფიზმი, განვი-
ხილოთ შემდეგი მაგალითი: დავუშვათ, საჭიროა გამოვთვალოთ მართკუთხედისა
და კვადრატის ფართობები ობიექტზე ორიენტირებული მიდგომით, ანუ შევქმნათ
კლასები და შესაბამისი მეთოდები.
პროგრამულ კოდს ექნება ქვემოთ წარმოდგენილი სახე:

class Rectangle: rect1=Rectangle(3,5)


def __init__(self, a, b): rect2=Rectangle(12,5)
self.a=a print("მართკუთხედის არეში შედეგი_1=", rect1.get_rect_area(), sep='')
self.b=b print("მართკუთხედის არეში შედეგი_2=", rect2.get_rect_area(), sep='')
def get_rect_area(self):
return self.a*self.b sq1=Square(5)
sq2=Square(7)
class Square: print("კვადრატის არეში შედეგი_1=", sq1.get_sq_area(), sep='')
def __init__(self, a): print("კვადრატის არეში შედეგი_2=", sq2.get_sq_area(), sep='')
self.a=a
def get_sq_area(self):
return self.a**2

gachechiladze_lela@yahoo.com 2
მე-2 სლაიდზე წარმოდგენილი
პროგრამული კოდის შესრულების
შედეგები:

დავუშვათ, გვინდა ჩვენი ყველა ობიექტი მოვათავსოთ ერთ კოლექციაში, მაგა-


ლითად, სიაში.
ნებისმიერი კოლექცია პითონში შეგვიძლია for ციკლით ვამუშავოთ. გამოვი-
ყენოთ ეს მიდგომა და ამავდროულად, ყოველი ობიექტისთვის მივმართოთ ფარ-
თობის გამოთვლის მეთოდს. ცხადია, სხვადასხვა კლასის ობიექტებს ფართობების
გამოთვლის სხვადასხვა მეთოდები აქვთ და არა საერთო. შესაბამისად, ვხვდებით
გარკვეულ ჩიხში (პროგრამული კოდი მომდევნო სლაიდზეა ნაჩვენები).
gachechiladze_lela@yahoo.com 3
მე-2 სლაიდზე წარმოდგენილი პროგრამული კოდის
მოდიფიცირებული ვერსია:
class Rectangle:
def __init__(self, a, b):
self.a=a
self.b=b
def get_rect_area(self): აღნიშნული კოდის შესრულებაზე გაშვება
return self.a*self.b აუცილებლად გამოიწვევს შეცდომას, რადგან
class Square: სხვადასხვა კლასის ობიექტებისთვის ფართო-
def __init__(self, a):
self.a=a ბის გამოთვლის მეთოდები განსხვავებულია.
def get_sq_area(self):
return self.a**2

rect1=Rectangle(3,5)
rect2=Rectangle(12,5)
print("მართკუთხედის არეში შედეგი_1=", rect1.get_rect_area(), sep='')
print("მართკუთხედის არეში შედეგი_2=", rect2.get_rect_area(), sep='')

sq1=Square(5)
sq2=Square(7)
print("კვადრატის არეში შედეგი_1=", sq1.get_sq_area(), sep='')
print("კვადრატის არეში შედეგი_2=", sq2.get_sq_area(), sep='')

figures=[rect1, rect2, sq1, sq2]


for figure in figures:
print(figure.get_rect_area())

gachechiladze_lela@yahoo.com 4
მე-4 სლაიდზე წარმოდგენილი პროგრამული კოდის
მოდიფიცირებული ვერსია:
ცხადია, გვაქვს შესაძლებლობა, for ციკლში დავსვათ პირობები და შესაბამისი
მეთოდები გამოვიძახოთ. ასე, მაგალითად:

class Rectangle:
def __init__(self, a, b):
self.a=a
self.b=b
def get_rect_area(self):
return self.a*self.b

class Square:
def __init__(self, a):
self.a=a
def get_sq_area(self):
return self.a**2

rect1=Rectangle(3,5)
rect2=Rectangle(12,5)
sq1=Square(5)
sq2=Square(7)
figures=[rect1, rect2, sq1, sq2]
for figure in figures:
if isinstance(figure, Rectangle):
print(figure.get_rect_area())
else:
print(figure.get_sq_area())

gachechiladze_lela@yahoo.com 5
მე-5 სლაიდზე წარმოდგენილი პროგრამული კოდის
მოდიფიცირების შესაძლებლობა
როგორ ვიქცევით იმ შემთხვევაში, თუ კვადრატის და მართკუთხედის ფართო-
ბების გარდა საჭირო გახდა წრის ფართობის გამოთვლაც? ცხადია, ვამატებთ ერთ
კლასს შესაბამისი მეთოდით, სიაში ვიხილავთ მის ობიექტებსაც და for ციკლში და-
მატებით პირობას ვსვამთ.
თუ სხვა გეომეტრიული ფიგურის ფართობის გამოთვლაც დაგვჭირდება, ის
კვლავ ახალი პირობის დამატებას მოითხოვს for ციკლში და ა.შ. ჩვენი კოდი საოც-
რად მოუქნელი გახდება (შესაბამისი პროგრამა მომდევნო სლაიდზეა წარმოდგე-
ნილი).

gachechiladze_lela@yahoo.com 6
მე-5 სლაიდზე წარმოდგენილი პროგრამული კოდის
მოდიფიცირებული ვერსია:
class Rectangle: rect1=Rectangle(3,5)
def __init__(self, a, b): rect2=Rectangle(12,5)
self.a=a
self.b=b sq1=Square(5)
def get_rect_area(self): sq2=Square(7)
return self.a*self.b
cir1=Circle(8)
class Square: cir2=Circle(9)
def __init__(self, a):
self.a=a figures=[rect1, rect2, sq1, sq2, cir1, cir2]
def get_sq_area(self): for figure in figures:
return self.a**2 if isinstance(figure, Rectangle):
print(figure.get_rect_area())
class Circle: elif isinstance(figure, Square):
def __init__(self, r): print(figure.get_sq_area())
self.r=r else:
def get_circle_area(self): print(figure.get_circle_area())
return 3.14*self.r**2

შედეგები:

gachechiladze_lela@yahoo.com 7
დასმული ამოცანის გადაწყვეტა პოლიმორფიზმის
გამოყენებით
იმისათვის, რომ პროგრამაში ყველა ობიექტთან ერთნაირად ვიმუშავოთ, ხოლო
ყოველმა ობიექტმა განსხვავებული ქცევა გამოავლინოს, საჭროა პოლიმორფიზმის
გამოყენება, რომლის გათვალისწინებით ჩვენი პროგრამული კოდი შემდეგ სახეს
მიიღებს:
class Rectangle: rect1=Rectangle(3,5)
def __init__(self, a, b): rect2=Rectangle(12,5)
self.a=a
self.b=b sq1=Square(5)
def get_area(self): sq2=Square(7)
return self.a*self.b
cir1=Circle(8)
class Square: cir2=Circle(9)
def __init__(self, a):
self.a=a figures=[rect1, rect2, sq1, sq2, cir1, cir2]
def get_area(self): for figure in figures:
return self.a**2 print(figure.get_area())

class Circle:
def __init__(self, r):
self.r=r
def get_area(self): შედეგები:
return 3.14*self.r**2

gachechiladze_lela@yahoo.com 8
პოლიმორფიზმის განხორციელება
მაგიური __str__ () მეთოდით
მეთოდებს, რომელთა სახელები (იდენტიფიკატორები) ორმაგი ხაზგასმით იწყე-
ბა და ასევე ორმაგი ხაზგასმით ბოლოვდება, პითონში მაგიურ მეთოდებს, ხშირად,
dunder-მეთოდებს უწოდებენ. მათ რიცხვს მიეკუთვნება ჩვენ მიერ უკვე განხილუ-
ლი მეთოდები:
 __init__() – კლასის კონსტრუქტორი, რომელიც ავტომატურად გამოიძახება
ობიექტების შექმნის დროს;
 __del__() – კლასის დესტრუქტორი, რომელიც ავტომატურად გამოიძახება
ობიექტების წაშლის დროს;
 __str__() – მეთოდი, რომელიც
ობიექტს გარდაქმნის სტრიქონულ
წარმოდგენად. ის გამოიძახება
მაშინ, როდესაც ობიექტი
გადაეცემა print() და str() ფუნქციებს;
 და სხვ.

gachechiladze_lela@yahoo.com 9
მე-8 სლაიდზე წარმოდგენილი პროგრამული კოდის
მოდიფიკაცია __str__ () მეთოდის ხელახალი განსაზღვრის გზით:
class Rectangle: rect1=Rectangle(3,5)
def __init__(self, a, b): rect2=Rectangle(12,5)
self.a=a sq1=Square(5)
self.b=b sq2=Square(7)
def __str__(self): cir1=Circle(8)
return "Rectangle area=" cir2=Circle(9)
def get_area(self):
return self.a*self.b figures=[rect1, rect2, sq1, sq2, cir1, cir2]
for figure in figures:
class Square: print(figure,figure.get_area())
def __init__(self, a):
self.a=a
def __str__(self): შედეგები:
return "Square area="
def get_area(self):
return self.a**2

class Circle:
def __init__(self, r):
self.r=r
def __str__(self):
return "Circle area="
def get_area(self):
return 3.14*self.r**2

gachechiladze_lela@yahoo.com 10
პოლიმორფიზმის განმარტება
პოლიმორფიზმი (ბერძნულიდან ნიშნავს „მრავალ ფორმას“) ობიექტზე ორიენ-
ტირებულ დაპროგრამებაში გულისხმობს ობიექტის უნარს, მოიქცეს სხვადასხვა-
გვარად.
დაპროგრამებაში პოლიმორფიზმის რეალიზება შესაძლებელია მეთოდის გადა-
ტვირთვის ან მისი ხელახალი განსაზღვრის გზით.
მეთოდის გადატვირთვა სტატიკურ პოლიმორფიზმს ემსახურება. აღნიშნულ
შემთხვევაში, მეთოდებს ერთნაირი სახელები (იდენტიფიკატორები), მაგრამ განსხ-
ვავებული პარამეტრების ტიპები და/ან მათი რაოდენობა აქვთ. აღნიშნულ მეთო-
დებს გადატვირთულს უწოდებენ.
დინამიკურ პოლიმორფიზმს მეთოდების ხელახალი განსაზღვრა იწვევს, სადაც
მშობელ კლასსა და წარმოებულ კლასში მეთოდებს ერთნაირი სიგნატურა გააჩნიათ.

gachechiladze_lela@yahoo.com 11
სტატიკური პოლიმორფიზმის მაგალითი
მეთოდების გადატვირთვა

class Rectangle: a=5; b=6; r=8


def __init__(self, a, b): rec=Rectangle(a,b)
self.a=a sq=Square(a)
self.b=b cir=Circle(r)
def area(self, a, b): print("მართკუთხედის არეში ფართობი=", rec.area(a,b), sep='')
return self.a*self.b print("კვადრატის არეში ფართობი=", sq.area(a), sep='')
print("წრის არეში ფართობი=", cir.area(), sep='')
class Square:
def __init__(self, a):
self.a=a
def area(self, a):
return self.a**2
შედეგები:
class Circle:
def __init__(self, r):
self.r=r
def area(self):
return 3.14*self.r**2

gachechiladze_lela@yahoo.com 12
დინამიკური პოლიმორფიზმი - მეთოდების ხელახალი
განსაზღვრა
class Parent:
def __init__(self, n): მოცემულ პროგრამულ კოდში method() სახე-
self.n=n
def method(self): ლის მქონე მეთოდს, ყოველი კლასის ობიექტი
s=0
while self.n!=0: ცალ-ცალკე იძახებს.
s+=self.n%10
self.n//=10
თუ გვსურს, რომ ქვეკლასიდან მოვახდინოთ
print("sum=", s, sep='') სუპერკლასის method() მეთოდის გამოძახება,
class Child(Parent): ქვეკლასში უნდა გამოვიყენოთ super() მეთოდი.
def __init__(self, n, x):
super(). __init__(n)
self.x=x შედეგები:
def method(self):
p=1
while self.x!=0:
p*=self.x%10
self.x//=10
print("mult=", p, sep='')
n=int(input("n="))
x=int(input("x="))
p=Parent(n)
ch=Child(n,x)
p.method()
ch.method()
gachechiladze_lela@yahoo.com 13
მე-13 სლაიდზე წარმოდგენილი პროგრამული კოდის
მოდიფიკაცია:
class Parent:
def __init__(self, n):
self.n=n
შედეგები:
def method(self):
s=0
while self.n!=0:
s+=self.n%10
self.n//=10
print("sum=", s, sep='')

class Child(Parent):
def __init__(self, n, x):
super(). __init__(n)
self.x=x
def method(self):
super().method()
p=1
while self.x!=0:
p*=self.x%10
self.x//=10
print("mult=", p, sep='')
n=int(input("n="))
x=int(input("x="))
ch=Child(n,x)
ch.method()

gachechiladze_lela@yahoo.com 14
გისურვებთ წარმატებულ სწავლას!

gachechiladze_lela@yahoo.com 15

You might also like