MySQL Java JavaScript PHP Python HTML-CSS C-sharp

Suprascrierea funcțonalității clasei de bază

În articolul anterior, clasa Employee prelua complet funcționalitatea clasei Person:

class Person:
   def __init__(self, name):
       self.__name = name   # numele persoanei

    @property
   def name(self):
       return self.__name

   def display_info(self):
       print(f"Nume: {self.__name}")

class Employee(Person):
   def work(self):
       print(f"{self.name} lucrează")

Dar ce facem dacă dorim să schimbăm ceva din această funcționalitate? De exemplu, să adăugăm un nou atribut pentru angajat, care să păstreze compania la care lucrează, sau să modificăm implementarea metodei display_info. Python permite suprascrierea funcționalității clasei de bază.

De exemplu, să modificăm clasele astfel:

class Person:
   def __init__(self, name):
       self.__name = name   # numele persoanei

    @property
   def name(self):
       return self.__name

   def display_info(self):
       print(f"Nume: {self.__name}")

class Employee(Person):
   def __init__(self, name, company):
       super().__init__(name)
       self.company = company

   def display_info(self):
       super().display_info()
       print(f"Companie: {self.company}")

   def work(self):
       print(f"{self.name} lucrează")

tom = Employee("Tom", "Microsoft")
tom.display_info()  # Nume: Tom
                   # Companie: Microsoft

Aici, în clasa Employee, se adaugă un nou atribut - self.company, care păstrează compania angajatului. Metoda __init__() primește trei parametri: al doilea pentru setarea numelui și al treilea pentru setarea companiei.

Dar dacă în clasa de bază este definit un constructor folosind metoda __init__, iar noi vrem să schimbăm logica constructorului în clasa derivată, trebuie să apelăm constructorul clasei de bază în constructorul clasei derivate. Adică în constructorul Employee trebuie să apelăm constructorul clasei Person.

Pentru a apela clasa de bază, se folosește expresia super(). Astfel, în constructorul Employee se face apelul:

super().__init__(name)

Această expresie va reprezenta apelul constructorului clasei Person, căruia i se transmite numele angajatului. Și aceasta este logic. De fapt, numele angajatului se setează în constructorul clasei Person. În constructorul Employee setăm doar proprietatea company.

În plus, în clasa Employee se suprascrie metoda display_info() - în ea se adaugă afișarea companiei angajatului. Am putea defini această metodă astfel:

def display_info(self):
   print(f"Nume: {self.name}")
   print(f"Companie: {self.company}")

Dar în acest caz, linia de afișare a numelui ar repeta codul din clasa Person. Dacă această parte a codului este aceeași cu metoda din clasa Person, nu are sens să ne repetăm, așa că folosim din nou expresia super() pentru a apela implementarea metodei display_info din clasa Person:

def display_info(self):
   super().display_info()      # apelarea metodei display_info din clasa Person
   print(f"Companie: {self.company}")

Apoi putem apela constructorul Employee pentru a crea un obiect al acestei clase și să apelăm metoda display_info:

tom = Employee("Tom", "Microsoft")
tom.display_info()

Afișarea în consolă a programului:

Nume: Tom
Companie: Microsoft

Verificarea tipului obiectului

În lucrul cu obiectele poate fi necesar, în funcție de tipul lor, să executăm anumite operațiuni. Cu ajutorul funcției încorporate isinstance(), putem verifica tipul obiectului. Această funcție primește doi parametri:

isinstance(object, type)

Primul parametru reprezintă obiectul, iar al doilea - tipul pentru care se face verificarea. Dacă obiectul reprezintă tipul specificat, funcția returnează True. De exemplu, să luăm următoarea ierarhie de clase Person-Employee/Student:

class Person:
   def __init__(self, name):
       self.__name = name   # numele persoanei

    @property
   def name(self):
       return self.__name

   def do_nothing(self):
       print(f"{self.name} nu face nimic")

# clasa angajatului
class Employee(Person):
   def work(self):
       print(f"{self.name} lucrează")

# clasa studentului
class Student(Person):
   def study(self):
       print(f"{self.name} studiază")

def act(person):
   if isinstance(person, Student):
       person.study()
   elif isinstance(person, Employee):
       person.work()
   elif isinstance(person, Person):
       person.do_nothing()

tom = Employee("Tom")
bob = Student("Bob")
sam = Person("Sam")

act(tom)    # Tom lucrează
act(bob)    # Bob studiază
act(sam)    # Sam nu face nimic

Aici, clasa Employee definește metoda work(), iar clasa Student - metoda study.

De asemenea, este definită funcția act, care verifică cu ajutorul funcției isinstance dacă parametrul person reprezintă un anumit tip și, în funcție de rezultatul verificării, apelează metoda corespunzătoare a obiectului.

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