Język programowania Python nie służy tylko i wyłącznie do tworzenia prostych skryptów. W poprzednim artykule: Pierwsze koty za płoty – Python – pierwsza aplikacja, miałeś okazję napisać swój pierwszy skrypt, kompletnie od początku. W ramach tego artykułu postaram Ci się wyjaśnić główne koncepcje związane z programowaniem zorientowanym obiektowo oraz jego podstawowe budulce takie jak klasy i obiekty.
Czym adekwatnie są te klasy i obiekty?
Klasy i obiekty są składowymi najpopularniejszego paradygmatu programowania, czyli obiektowego. Pozwala on na tworzenie systemu składającego się z wielu elementów, które ze sobą współpracują, zachowując ich prostotę. Wiem, na ten moment może wydawać się to niezrozumiałe, ale w dalszej części tego artykułu postaram Ci się to wyjaśnić, ale najpierw przedstawię trochę teorii, którą następnie będziesz miał okazję sprawdzić w przedstawionych przykładach.
Programowanie zorientowane obiektowo (klasy i obiekty)
Programowanie zorientowane obiektowo to paradygmat programowania, który zakłada traktowanie elementów programów jako obiektów. Główne koncepcje paradygmatu obiektowego to:
– enkapsulacja – polega na ukrywaniu szczegółów implementacyjnych obiektów i udostępnianiu jedynie niezbędnych funkcjonalności
– dziedziczenie – pozwala na tworzenie hierarchii klas, w których określone klasy dziedziczą pewne cechy po innych klasach
– polimorfizm – umożliwia przesyłanie tych samych wiadomości do różnych obiektów i uzyskanie różnych wyników
– abstrakcja – polega na wyodrębnianiu cech charakterystycznych dla danej klasy i tworzeniu ogólnych definicji
– interfejsy – pozwala na zdefiniowanie metod, które muszą być zaimplementowane przez klasy, które je implementują.
Koncepcje te pozwalają na tworzenie bardziej elastycznych, skalowalnych i łatwiejszych w obsłudze programów. Programowanie obiektowe jest stosowane w różnego rodzaju programach, w tym w systemach informatycznych, aplikacjach internetowych oraz grach komputerowych.
Klasy
Powyższy kot w odniesieniu do programowania jest obiektem klasy kot. Sama idea klasy służy do przedstawienia wycinka rzeczywistości/pojęcia w kontekście programistycznym. Przyjmijmy koty posiadają jakieś imię(name), rasę(breed) oraz jakieś typowe kocie zachowania, jak np. to iż można go zawołać (wykorzystując jego imię) oraz może wykonywać typowo kocie rzeczy czyli np. miauczeć, drapać, pić mleko itp. W ten sposób opisaliśmy pojęcie jakim jest kot, bez odnoszenia tego do konkretnego zwierzęcia. Wykorzystajmy teraz tą wiedzę do zdefiniowania klasy Cat:
Powyższy kod opisuje kota w sposób abstrakcyjny. Określa jego zmienne takie jak imię oraz rasę (póki co ustawiona na wartość Cat) oraz typowe kocie zachowania. Jest to próba ogólnego opisu tego czym są koty i jak się zachowują. Konkretny żyjący kot jest tak naprawdę obiektem utworzonym z wykorzystaniem konkretnego szablonu, jakim jest klasa. Przejdźmy teraz do analizy kodu klasy w celu wyjaśnienia jej konkretnych elementów składowych.
Właściwości
Metody
Metody klas, podobnie jak funkcje mogą przyjmować argumenty, czyli zmienne przekazywane do obiektu w celu wykonania jakiegoś zachowania. Specyficzną rzeczą dla Pythona jest to, iż definiując funkcje, jako pierwszy argument należy wskazać zmienną, do której zostanie przekazany obiekt, na którym wywoływane jest dane zachowanie. W przykładowym kodzie jest to zmienna self. Następnie można zdefiniować dodatkowe zmienne, które będą konieczne do wykonania zachowania.Metoda __init__ jest tzw. konstruktorem obiektu, prościej mówiąc służy ona do utworzenia nowej instancji obiektu danej klasy. Efektem jej wywołania jest utworzenie oraz zapisanie w pamięci komputera obiektu danej klasy.
Ważnym elementem, który należy zapamiętać jest to, iż klasa sama w sobie jest tylko wzorcem, który opisuje obiekty. Podczas działania aplikacji wykorzystuje się obiekty, które zostały stworzone według wzoru przedstawionego przez klasę.
Obiekty
Skoro wiesz już czym są klasy i iż są one bardzo mocno powiązane z obiektami, to teraz należy zrozumieć czym jest ten cały obiekt. Obiekt jest to główny element programowania zorientowanego obiektowo. Jest on tworzony według konkretnego szablonu (klasy), która opisuje adekwatności oraz metody przez niego udostępniane. Nawiązując do przykładu żywego kota, w świecie programowania można przyjąć, iż jest on obiektem klasy kot o konkretnej rasie oraz imieniu. Przyjrzyjmy się teraz w jaki sposób możemy stworzyć swojego nowego kota dzięki języka Python:
W powyższym przykładzie utworzyliśmy nową instancje obiektu klasy Cat oraz przypisaliśmy ją do zmiennej o nazwie cat. Dzięki przypisaniu obiektu do zmiennej, możemy dostać się do składowych konkretnej klasy tj. do rasy kota oraz możemy uruchomić jego konkretne zachowania takie jak call oraz meow. Rezultatem uruchomienia takiego skryptu będzie wypisanie na oknie konsoli poniższych informacji:
Przeanalizujmy linię 14-17 przykładowego kodu. Pierwsza z nich odpowiada za wywołania konstruktora klasy Cat oraz przypisaniu imienia konkretnego konkretnego kota. Następna linijka wypisuje na oknie konsoli jego imię oraz w kolejnych liniach wywołujemy jego konkretne zachowania, takie jak: zawołaj i zamiaucz.
Wszystko jasne, ale co w przypadku gdy chcę mieć więcej niż 1 kota? Nic trudnego należy utworzyć kolejną instancję obiektu i przypisać ją do nowej zmiennej:
W powyższym przykładzie w linii 19 została utworzona nowa instancja klasy Cat z imieniem Devkot, dzięki czemu masz 2 niezależne koty żyjące w pamięci Twojego komputera, sic! Aby lepiej zasymulować interakcje między kotami przyjmijmy iż mogą się ona nawzajem podrapać.
Efektem uruchomienia tego kodu będzie:
Jak widzisz na powyższym zrzucie ekranu kot Kociak podrapał kota Devkot. W ten oto sposób udało się nam stworzyć zachowania, które angażują inny obiekt do wykonania konkretnego zachowania. Wykorzystaliśmy argumenty przekazywane do metody, dzięki których wskazaliśmy, który kot został podrapany.
Obiekty - jak są przechowywane w pamięci komputera
Zastanawiasz się jak to się dzieje, iż komputer był w stanie przekazać konkretny obiekt jako argument do metody innego obiektu. Jest to możliwe dzięki temu jak jest zbudowana pamięć w komputerze oraz dzięki temu, iż zmienne, które przechowują obiekt tak naprawdę przechowują adres do miejsca w pamięci, gdzie ten obiekt się znajduje, czyli przechowują referencję do obiektu.
Referencja w Pythonie to sposób, w jaki program odwołuje się do konkretnych obiektów w pamięci. Kiedy tworzysz nowy obiekt, Python rezerwuje dla niego miejsce w pamięci komputera. Referencja zawiera informację o adresie w pamięci, gdzie znajduje się ten obiekt. Zapisanie referencji do zmiennej oznacza, iż ta zmienna wskazuje na dany obiekt.
Dzięki temu mechanizmowi, gdy przekazujesz obiekt do innej metody lub funkcji tak naprawdę informujesz ją, gdzie w pamięci komputera powinien jej szukać, czyli przekazujesz jej adres.
Więcej na temat organizacji pamięci w komputerach możesz przeczytać w ramach tego artykułu: STOS I STERTA. KONFRONTACJA STRUKTUR DANYCH. Szczerze polecam zapoznać się z tym artykułem.
Mam nadzieję, iż ilość teorii Ciebie nie przeraziła, ale to na dziś tyle. W ramach kolejnych artykułów skupimy się na pojęciach stricte związanych ze światem programowania obiekt ego takimi jak: dziedziczenie, polimorfizm, interfejsy oraz przyjrzymy się ogólnym zasadom tworzenia dobrego i jakościowego kodu.
Do zobaczenia w kolejnym artykule!