8.1 Polimorfizm
Polimorfizm obyekt yönümlü proqramlaşdırmanın (OOP) əsas anlayışlarından biri kimi, fərqli sinifdən olan obyektlərə eyni interfeysi istifadə etməyə imkan yaradır.
Python-da polimorfizm dinamik tipizasiya və irsiyyət vasitəsilə əldə edilir. Polimorfizmin mühüm tərəfi metodların üstələnməsi və baza sinifinin metodlarının alt-sinifin metodları ilə əvəz olunmasıdır.
Polimorfizmin əsas anlayışları:
Fərqli obyektlər üçün vahid interfeys:
Polimorfizm fərqli siniflərin obyektləri üçün vahid interfeysdən istifadə etməyə imkan verir ki, bu da metodların müxtəlif realizasiyaya malik olmasına şərait yaradır.
Dinamik tipizasiya:
Python-da dəyişənin tipi icra zamanı təyin olunur ki, bu da funksiyaların tələb olunan interfeysi dəstəkləyən istənilən sinifdən olan obyektlərlə işləməsinə imkan yaradır.
İrsiyyət:
Sinif iyerarxiyasını yaratmağa imkan verir ki, burada alt-siniflər baza sinifinin xassə və metodlarını irs alır, lakin onları öz spesifik funksionallığı üçün yenidən təyin edə bilər.
Polimorfizm nümunələri:
Polimorfizmin sadə bir nümunəsi: üç sinifin hər biri move()
adlı metoda sahibdir. Bu o deməkdir ki, biz eyni vaxtda bu obyektlərlə işləyə bilən kod yaza bilərik.
class Car:
def move(self):
pass
class Human:
def move(self):
pass
class Bird:
def move(self):
print("Karr!")
car = Car()
human = Human()
bird = Bird()
for it in [car, human, bird]:
it.move()
Bu halda «ümumi interfeys» metodun adı, yaxud parametrə malikdirsə, onun siqnatı hesab olunur.
8.2 Metodların yenidən təyin edilməsi
Polimorfizm tez-tez irsiyyətlə birlikdə istifadə olunur və bu, ümumi interfeysi təyin edən baza sinifinin olduğu, sub-siniflərin isə spesifik detalı reallaşdırdığı sinif iyerarxiyalarını yaratmağa imkan verir.
class Employee:
def get_salary(self):
return 1000
class FullTimeEmployee(Employee):
def get_salary(self):
return 5000
class PartTimeEmployee(Employee):
def get_salary(self):
return 3000
class Intern(Employee):
pass
def print_salary(employee):
print(employee.get_salary())
employees = [FullTimeEmployee(), PartTimeEmployee(), Intern()]
for employee in employees:
print_salary(employee)
Bu nümunə əvvəlki ilə oxşardır, lakin mühüm fərq var — bizim siniflərimiz mütləq get_salary
metoduna malik olmalıdır, çünki bu metod həmişə baza sinifində mövcuddur. İndi bütün siniflərin «ümumi interfeysi» sadəcə get_salary()
metodu deyil, məhz bütün metod və atributları ilə birlikdə Employee
sinifidir.
8.3 Varislik sinfinin metodlarını çağırmaq
Aşağıdakı koda diqqətlə baxın:
Biz print_salary()
metodunu çağırırıq, o yalnız əsas Employee sinfində mövcuddur və o artıq əsas sinfin başqa bir metodunu çağırır — get_salary()
. Beləliklə, ekranda hansı maaşlar göstəriləcək?
class Employee:
def print_salary(self):
salary = self.get_salary()
print(salary)
def get_salary(self):
return 1000
class FullTimeEmployee(Employee):
def get_salary(self):
return 5000
class PartTimeEmployee(Employee):
def get_salary(self):
return 3000
class Intern(Employee):
pass
employees = [FullTimeEmployee(), PartTimeEmployee(), Intern()]
for employee in employees:
employee.print_salary()
Əhəmiyyətlidir!
Aşağıda yazılanları oxuyun — bu əhəmiyyətlidir.
Əgər print_salary()
metodunu, məsələn, FullTimeEmployee
sinfi üzrə çağırsanız, onda o əsas sinfin metodu çağırılacaq, çünki həmin sinfə aid belə bir metod elan edilməyib.
Amma print_salary()
metodu self
obyektindən istifadə edərək get_salary()
metodunu çağıracaq. Bu obyektin tipi isə FullTimeEmployee
-dir, Employee
deyil. Buna görə də məhz FullTimeEmployee
sinfindən get_salary()
metodu çağırılacaq!
Üstəlik, FullTimeEmployee
sinfi əsas sinfin get_salary()
metodunu öz tələbləri üçün istifadə edə bilər. Məsələn, biz maaşı əsas məvacibdən faizlə hesablamalıyıq:
class FullTimeEmployee(Employee):
def get_salary(self):
base_salary = super().get_salary()
return base_salary * 5
# 500%
class PartTimeEmployee(Employee):
def get_salary(self):
base_salary = super().get_salary()
return base_salary * 3 # 300%
8.4 Metodların overload-u
Python-da metodların overload-u (method overloading)
— eyni adla, amma fərqli parametrlərlə bir neçə metod yaratmaq qabiliyyətidir. Lakin, metodların overload-u, digər proqramlaşdırma dillərində olduğu kimi (məsələn, C++ və ya Java), Python-da natamam şəkildə dəstəklənir.
Python-da metodların overload-unu default argumentlər, *args
və **kwargs
vasitəsi ilə təqlid etmək olar.
Metodların overload-u üzrə nümunələr
Müxtəlif miqdarda ötürülən argümentlərə görə müxtəlif davranışlar sərgiləyən funksiyanı işləyə bilərik. Bunu fərqli üsullarla etmək mümkündür, məsələn:
class Example:
def display(self, a=None, b=None):
if a is not None and b is not None: print(a, b)
elif a is not None: print(a)
else: print("Argüment yoxdur")
obj = Example()
obj.display(1, 2) # Nəticə: 1 2
obj.display(1) # Nəticə: 1
obj.display() # Nəticə: Argüment yoxdur
Həmçinin ötürülən məlumatların tipini də nəzərə almaq olar — sadəcə tipə baxış etmək kifayətdir:
class Example:
def mod(self, a, b):
if type(a) == int and type(b) == int: print(a % b)
elif type(a) == float or type(b) == float: print(round(a / b))
else: print("Kömək təlimatı: a və b int və ya float olmalıdır")
obj = Example()
obj.mod(5, 2) # Nəticə: 1
obj.mod(5.0, 2) # Nəticə: 2
obj.mod("5", 2) # Nəticə: Kömək təlimatı: a və b int və ya float olmalıdır
Əgər düzgün olmayan məlumat tipləri ötürülərsə, təlimat və ya hətta internetdə mövcud olan sənədlərin linkini göstərmək olar — bu da olduqca populyar bir həldir.
GO TO FULL VERSION