Współczesne języki programowania, zarówno te kompilowane jak i interpretowane, wykorzystują koncepcję programowania obiektowego. Polega ona na modularyzowaniu kodu programu na małe funkcjonalne części zwane obiektami. Są to swego rodzaju “klocki”, z których następnie składamy cały program. Są one na tyle uniwersalne, że używamy je w różnych programach. Obiekty te nazywane są klasami, które składają się z atrybutów (zmiennych) oraz metod (funkcji). Jedną ze specjalnych funkcji jest konstruktor klasy.
Gdy rodzi się obiekt
Gdy w programie napisanym w dowolnym języku programowania obiektowego tworzymy nowy obiekt, to wywoływana jest specjalna funkcja zwana konstruktorem klasy. W dokumentacji języka Python nie znajdziemy tej nazwy wprost wyrażonej. Ma ona jednak to samo zadanie co konstruktory klas znane z języka C++ czy Java. Dlatego nie popełniamy błędu, jeżeli nazywamy tą metodę konstruktorem. Nadajemy jej ściśle określoną nazwę: __init__()
.
Konstruktor w klasie nie jest elementem obowiązkowym. Jeżeli jednak tą metodę zdefiniujemy, to będzie ona wykonana jako pierwsza po zainicjowaniu obiektu. Nie musimy wywoływać jej ręcznie. Za jej pomocą ustawimy choćby wartości zmiennym klasy, czy mówiąc bardziej ogólnie przystosujemy klasę do naszych celów. Spójrzmy na poniższy przykład:
class Punkt: x = None y = None def __init__(self): self.x = 1 self.y = 2 def pozycja(self): print("(%s,%s)" % (self.x, self.y)) p = Punkt() p.pozycja()
Uruchomienie tego programu pokaże nam na ekranie wynik:
(1,2)
Zdefiniowana przeze mnie klasa ma dwa atrybuty (zmienne), których wartość ustawiam za pomocą konstruktora. Oczywiście mógłbym im wartość przypisać w definicji samych obiektów.
class Punkt: x = 2 y = 3 def pozycja(self): print("(%s,%s)" % (self.x, self.y)) p = Punkt() p.pozycja()
Takie podejście jest jednak niepraktyczne, z jednego ważnego powodu.
Konstruktor z parametrami
Zazwyczaj powołując nowy obiekt do życia pewne jego cechy ustawiamy na etapie jego tworzenia, gdyż ich wartość wynika z poprzednio wykonanych przez nasz program czynności, albo wprowadzonych przez użytkownika danych. Dlatego konstruktor może przyjmować parametry swojego wywołania. Przekazujemy je przy tworzeniu obiektu.
class Punkt: x = None y = None def __init__(self, moj_x, moj_y): self.x = moj_x self.y = moj_y def pozycja(self): print("(%s,%s)" % (self.x, self.y)) p = Punkt(2,3) p.pozycja()
W tym wypadku podaliśmy parametry zmiennych tworząc obiekt typu Punkt
, i za pomocą konstruktora przypisaliśmy je atrybutom naszej klasy. W wyniku działania powyższego kodu na ekranie zobaczymy:
(2,3)
Tak jak jest funkcja będąca konstruktorem klasy, tak jest też i specjalna funkcja wywoływana przy usuwaniu obiektu z pamięci, tak zwany destruktor. Metoda ta nosi nazwę __del__()
.