MySQL Java JavaScript PHP Python HTML-CSS C-sharp

Clase și metode abstracte

De obicei, clasele reflectă anumite obiecte din realitatea înconjurătoare. Însă uneori lucrăm cu entități care nu au o întruchipare concretă. De exemplu, entitatea „animal”. Există animale concrete - pisică, câine și așa mai departe, dar animalul ca atare nu are o întruchipare concretă. Sau entitatea „figură geometrică”. Există dreptunghi, pătrat, cerc, triunghi, dar figura geometrică în sine nu are o întruchipare concretă. De obicei, pentru a descrie astfel de entități se folosesc clase abstracte.

În limbajul Python, toate instrumentele pentru crearea claselor abstracte sunt definite într-un modul special numit abc, care trebuie să fie inclus suplimentar în aplicație.

import abc

Componenta cheie a acestui modul este clasa ABC și adnotarea @abstractmethod. Clasa ABC simplifică crearea unei clase abstracte, iar toate clasele abstracte definite sunt derivate din această clasă. Adnotarea @abstractmethod este destinată creării unei metode abstracte.

Clasele abstracte sunt definite ca și clasele obișnuite, cu excepția faptului că acestea sunt derivate din clasa ABC din modulul abc. De exemplu, să definim o clasă abstractă pentru o figură geometrică:

import abc

class Shape(abc.ABC):
   pass

De obicei, clasele abstracte declară un anumit funcțional comun pentru clasele derivate. În plus, unele funcționalități pot să nu aibă nicio implementare - implementarea acestora trebuie să fie definită de clasele derivate. Acest tip de funcționalitate este reprezentat în cadrul clasei prin metode abstracte.

De exemplu, clasa figurii geometrice poate avea metode pentru calcularea perimetrului, a ariei etc. Nu putem defini o formulă generală pentru calcularea ariei tuturor figurilor - pentru fiecare figură concretă, principiul de calcul al ariei poate fi diferit. Prin urmare, în clasa figurii putem defini metoda de calcul al ariei ca abstractă. Pentru aceasta se folosește adnotarea @abstractmethod din modulul abc:

import abc

class Shape(abc.ABC):
    @abc.abstractmethod
   def area(self):
       pass  # aria figurii

În acest caz, metoda area() este definită ca abstractă. Deoarece nu are nevoie de o funcționalitate concretă, în interiorul ei este folosit operatorul pass.

Este important de menționat că nu putem crea direct un obiect al unei clase abstracte cu metode abstracte, folosind constructorul său:

import abc

class Shape(abc.ABC):
    @abc.abstractmethod
   def area(self):
       pass  # aria figurii

shape = Shape()  # ! Eroare - acest lucru nu este permis
print(shape)

Clasele derivate trebuie să implementeze toate metodele abstracte ale clasei abstracte. De exemplu, să definim clasa pentru un dreptunghi:

import abc

class Shape(abc.ABC):
    @abc.abstractmethod
   def area(self):
       pass  # aria figurii

# clasa dreptunghiului
class Rectangle(Shape):
   def __init__(self, width, height):
       self.width = width
       self.height = height

   def area(self):
       return self.width * self.height

rect = Rectangle(30, 50)
print("Rectangle area:", rect.area())  # Rectangle area: 1500

Aici, clasa dreptunghiului Rectangle primește prin constructor lățimea și înălțimea și le folosește pentru a calcula aria în metoda area().

În mod similar, putem defini și alte tipuri de figuri. De exemplu, să adăugăm clasa pentru un cerc:

import abc

class Shape(abc.ABC):
    @abc.abstractmethod
   def area(self):
       pass  # aria figurii

# clasa dreptunghiului
class Rectangle(Shape):
   def __init__(self, width, height):
       self.width = width
       self.height = height

   def area(self):
       return self.width * self.height

# clasa cercului
class Circle(Shape):
   def __init__(self, radius):
       self.radius = radius

   def area(self):
       return self.radius * self.radius * 3.14

def print_area(shape):
   print("Area:", shape.area())

rect = Rectangle(30, 50)
circle = Circle(30)
print_area(rect)  # Area: 1500
print_area(circle)  # Area: 2826.0

În acest caz, pentru a afișa aria figurii, a fost definită funcția print_area, care acceptă orice figură.

În același timp, clasele abstracte pot defini și constructori, atribute, metode neabstracte, care pot fi folosite și în clasele derivate:

import abc

class Shape(abc.ABC):
   def __init__(self, x, y):
       self.x = x
       self.y = y

    @abc.abstractmethod
   def area(self):
       pass  # metodă abstractă

   def print_point(self):  # metodă neabstractă
       print("X:", self.x, "\tY:", self.y)

# clasa dreptunghiului
class Rectangle(Shape):
   def __init__(self, x, y, width, height):
       super().__init__(x, y)
       self.width = width
       self.height = height

   def area(self):
       return self.width * self.height

rect = Rectangle(10, 20, 100, 100)
rect.print_point()  # X: 10   Y: 20

Aici, clasa abstractă Shape primește prin constructor coordonatele X și Y pentru un punct, în raport cu care este creată figura (de exemplu, pentru un dreptunghi, acestea pot fi coordonatele colțului din stânga sus, pentru un cerc - centrul). De asemenea, este definită o metodă neabstractă print_point, care afișează coordonatele punctului pe consolă.

← Lecția anterioară Lecția următoare →