Trochę o OOP
OOP jest już dostępne w coraz to większej ilości języków programowania. Właściwie język bez obsługi OOP, chociaż w podstawowym stopniu, nie ma już racji bytu. Prawdziwy bum na programowanie obiektowe miał miejsce, gdy pojawiła się nowa wersja PHP oznaczona numerem 5 (co prawda wcześniejsze wersje też udostępniały klasy i obiekty, ale nie można było tego nazwać nawet szczątkową obsługą OOP). Gros osób piszących właśnie w tym języku odkryło możliwości jakie niosła ze sobą, zupełnie nowa dla niektórych, funkcjonalność. Zauważyłem jednak, że wielu młodych programistów nie rozumie na czym tak na prawdę polega programowanie obiektowe. W internecie znajduje się wiele "kursów" używających sławnych już przykładów "pojazd - rower" lub "roślina - kwiat". Nie zawsze jednak takie porównania pozwalają w pełni zrozumieć ideę OOP.
Chcę jeszcze pokrótce wyjaśnić dlaczego warto zainteresować się programowaniem zorientowanym obiektowo. Pierwszym, i chyba najważniejszym, jest abstrakcyjność. Kiedy używamy jakiejś klasy/obiektu nie musimy znać dokładnie sposobu w jaki on funkcjonuje. Wystarczy, że opanujemy dostępne w nich metody, aby skutecznie nimi manipulować. Drugą ważną cechą jest łatwość późniejszego rozwoju aplikacji. Aby wprowadzić nową funkcjonalność, lub stworzyć nową nie trzeba modyfikować kodu w wielu miejscach. W pewien sposób cecha ta łączy się z pierwszą. Wszystkie zmiany można ukryć wewnątrz klas, co umożliwi nam pozostawienie właściwego kodu aplikacji bez zmian. Ostatnią własnością OOP jest lepsze odzwierciedlenie sposobu myślenia zwykłego człowieka. Zamiast wywoływania funkcji, nie mających wiele wspólnego z rzeczywistością wykonuje się operacje na "realnych obiektach" takich jak plik, pozycja w menu strony, lub też użytkownik serwisu internetowego.
Zakładam, że znane są Ci pojęcia takie jak klasa, obiekt, metoda itp. Nie będę ich tutaj objaśniał, gdyż w internecie dostępnych jest mnóstwo materiałów na ten temat. Na początek chcę rozdzielić dwa, najczęściej używane typy klas. Od strony technicznej nie różnią się one od siebie niczym, cały mankament tkwi w podejściu do użyteczności klasy. Pierwszy typem (określanym przeze mnie jako typ podstawowy) jest klasa rzeczywista. Są to klasy reprezentujące "realne obiekty" wymienione w poprzednim akapicie. Można je określić jako opis własności każdego z tych przedmiotów. Dodatkowo wewnątrz takiej klasy możemy stworzyć metody (operacje) realizujące różne czynności związane z obiektem. Posłużę się często używanym w praktyce przykładem, który powinien w lepszym stopniu odzwierciedlać ideę klasy rzeczywistej.
Klasa news: # własności - identyfikator - tytuł - treść - autor - data dodania - grafika #metody - zapisz - skasuj - ustaw tytuł - ustaw treść - ustaw autora - ustaw datę dodania - ustaw grafikę - konstruktor #pobiera z bazy dane newsa o podanym identyfikatorze, jeśli nie podany żaden identyfikator pozostawia pusty obiekt
Jak widać powyższa klasa określa prostego newsa, na którego składają się podstawowe elementy - własności. Do obsługi (tj. zmiany, usunięcia) obiektów tej klasy służą zdefiniowane metody. Oto przykład praktycznego użycia tej klasy (nazwy metod i własności zostały nieco zmienione ze względu na wymagania języka programowania).
<?php # Utworzenie nowego obiektu i zapisanie go w bazie $news = new news(); $news->ustawTytul("Przykładowy news"); $news->ustawTresc("Lorem ipsum dolor sit amet enim. Etiam ullamcorper. Suspendisse a pellentesque dui, non felis. Maecenas malesuada elit lectus felis, malesuada ultricies."); $news->ustawAutora("Jony"); $news->ustawGrafikę("/grafiki/news.png"); $news->zapisz(); ?> <?php # Pobranie "obiektu" z bazy i usunięcie go $news = new news(2); $news->usun(); ?>
Jeśli jesteś początkującym programistą PHP to widzisz, że kod staje się bardziej przejrzysty. Ominięta została warstwa obsługi bazy danych - to jest właśnie abstrakcja. Cała logika operacji została usunięta z kodu programu. Jeśli chcesz zmienić sposób łączenia się z bazą wystarczy zmodyfikować klasę, a program pozostaje bez zmian.
Drugim typem klas są klasy biblioteczne. W przeciwieństwie do typu omawianego przed chwilą, ten nie reprezentuje żadnego "rzeczywistego" obiektu, a jest jedynie zbiorem funkcji (metod). Można na przykład stworzyć klasę realizują różne sposoby szyfrowania i deszyfrowania danych.
Klasa szyfrowanie: - szyfruj md5 - szyfruj sha - szyfruj RSA - deszyfruj RSA
Metody zawarte w tej klasie zwane są metodami statycznymi. Oznacza to, że nie wykonują operacji na konkretnej instancji danej klasy (tj. na konkretnym obiekcie). Można je wywoływać bez tworzenia obiektu.
<?php $ciag = 'Ala ma kota'; $hash = szyfrowanie::szyfrujSha($ciag); ?>
Podsumowując... klasa powinna reprezentować pewien obiekt (rzeczywisty lub wirtualny), wtedy jest nazywana klasą rzeczywistą. Innym celem użycia klas może być zgromadzenie funkcji o podobnym zastosowaniu w jednym miejscu w celu łatwiejszego ich późniejszego użycia, wtedy mówimy o klasie bibliotecznej. Mam nadzieję, że nieco przybliżyłem główną ideę programowania obiektowego i chociaż część młodych programistów czytających ten wpis zrozumie o co w tym wszystkim chodzi :)
Na koniec mam jeszcze dość ważną uwagę do wszystkich (doświadczonych i tych początkujących). Użyte pojęcia, które są pochylone nie są powszechnie znane, ani używane. Są jedynie moim własnym wymysłem i mają na celu łatwiejszy przekaz mojego sposobu rozumowania i łatwiejszego kojarzenia niektórych elementów.
15 komentarzy
Nie, żebym chciał wzniecać flejmy, czy ubliżać autorowi, ale moim zdaniem języki "przeznaczone do porogramowania zorientowanego obiektowo" to głupota. Przekonałem się o tym przechodząc na C po kilku "nowoczesnych językach" takich jak Java, czy D, a także C++.
Co z tego wynikło? Okazuje się, że można bardzo łatwo programować obiektowo w C, mając nawet polimorfizm, a także enkapsulację, jeśli ktoś się uprze, a przy tym ma się dużo więcej w wolności dzięki czemu można nagiąć zasady, gdy tylko przyjdzie ochota. To lubię! :)
@Elwis:
Również "przechodziłem" przez wiele języków programowania - jednak teraz zostałem przy duecie Python + C, czasem PHP i Java (wiadomo - co jest w danej sytuacji wygodniejsze to w tym piszę). Większość aplikacji jakie robię są pisane "do szuflady" - Python w zupełności starcza. Gdy trzeba większej szybkości piszę małe rozszerzenie w C i wszystko gra :) A poza tym uwielbiam pisać w GTK+ :)
Teraz gdy patrzę na moje wcześniejsze kody źródłowe, dajmy na to w C++, to ciarki mnie przechodzą jak widzę STL'a choć to można jeszcze przeżyć - C++ ma wiele gorszych dziwactw ("Co to jest 'public static virtual volatile register void**' i kiedy ostatnio go używałeś?")
@post:
Mam nadzieję, że ten post przerodzi się w jakiś mini kurs lub chociaż doczeka się rozwinięcia, bo choć dobre to jest to tylko wprowadzenie.
No bo w większości książek z podstawami, które czytałem przykłady są potwornie oderwane od rzeczywistości.
A po co tak na prawdę jest to całe OOP to można się przekonać po zrozumieniu wzorców projektowych.
Po pierwsze, nie `gro` tylko `gros`
Po drugie, boom na języki obiektowe miał miejsce dużo wcześniej niż pojawiła się piąta wersja php.
Martinez i chyba wcześniej niż php 4.
Oczywiście warto sobie zadać pytanie czy C++ i PHP są w pełni obiektowe.
Wzorce są potężne jeśli ktoś je dobrze pozna to niechętnie będzie odchodził od OOP. Jednak dobre OOP to przede wszystkim sposób myślenia by nie zrobić jakiegoś gniota, który korzysta z klas, dziedziczenia itp., ale sam w sobie jest zwykłym gniotem i porozrzucaną logiką na wiele klas.
> Oczywiście warto sobie zadać pytanie czy C++ i PHP są w pełni obiektowe.
C++? Oczywiście że jest. A że pozwala na użycie też innego paradygmatu programowania, to zupełnie inna sprawa.
Jeżeli mówimy o programowaniu OOP to stricte obiektowym językiem jest np. JAVA :P PHP w tym względzie nawet w wersji 5 odbiega od założenia obiektowości :P
Sznurek: 'public static virtual volatile register void**' to błąd składniowy.
Programowanie OO to podstawa, trochę dziwi mnie to zdanie "warto się zapoznać" OO to podstawa. Oczywiście znajomość, klas, obiektów to nie OO. Jak ktoś dobrze zwrócił uwagę OO to wzorce projektowe i ich prawidłowe wykorzystanie. PHP 5 ma mało wspólnego z OO, języki w pełni obiektowe to, np. Java. Fachowa lektura do OO to, np. seria Head First. http://helion.pl/ksiazki/hfjava.htm
http://helion.pl/ksiazki/hfdepa.htm
http://helion.pl/ksiazki/hfooad.htm
@Elwis: zależy co kto lubi.
@Sznurek: teraz będę miał dość dużo wolnego czasu, żeby nad czymś posiedzieć. Nie chcę robić postów, tylko po to żeby były. Już kiedyś miałem taką sytuację i źle to się skończyło. Pożyjemy, zobaczymy.
@martinez: poprawione :P
Należy jednak zwrócić uwagę na to, że kiedy w PHP pojawiła się obiektowość duża liczba młodych programistów wpłynęła na głęboką wodę. Kiedy jeszcze PHP nie było tak bardzo popularne programowaniem zajmowali się prawie wyłącznie profesjonaliści i pasjonaci. Teraz znajomość przynajmniej podstaw programowania to niemal konieczność, a wile osób zaczyna właśnie od PHP.
Stricte obiektowy to jest Ruby lub Python, gdzie można wywoływać metody na liczbach: 5.next (liczby i łańcuchy są tam obiektami).
C++ jest dosyć mocno obiektowe (i nie tylko), ale to stary język niosący jeszcze zaszłości z C. Java do topowo obiektowych może nie należy, ale faktycznie wszystko, co ma związek z Javą jest robione mocno obiektowo. Czasami zbyt mocno, do tego stopnia, że aż pisanie niektórych rzeczy jest po prostu niewygodne i boli.
Jony: Zgodzę się, że gdy w PHP pojawiła się namiastka obiektowości, to nie tylko profesjonaliści i pasjonaci zainteresowali się OOP. Tylko — kto, jeśli nie profesjonaliści i pasjonaci? Oczywiście programiści z trzeciej ręki, siódmego odzysku i piątego terminu ważności. Tj. tacy, który tak naprawdę w ogóle programowaniem nie powinni się zajmować, a raczej może łowieniem ryb. ;þ
BTW, Sznurek: "Co to jest 'public static virtual volatile register void**'?" — nic. Nie ma takiej konstrukcji w C++. ;þ
@mcv: Nie spisuj wszystkich na straty... niektórzy chcą się zająć programowaniem na serio, tylko czerpią wiedzę z nieodpowiednich źródeł :P
Racja, człowiek istota niedoskonała, ma skłonności do przesadzania. ;-)
BTW, Sznurek: "Co to jest 'public static virtual volatile register void**'?" — nic. Nie ma takiej konstrukcji w C++. ;þ
Ech, zapędziłem się: public: static volatile void** - szukałem cytatu (coś o wirtualnych (...) destruktorach, ale nie znalazłem ;p). Zapędziłem się ze słowami kluczowymi :) (ale teraz to traci trochę sens - sam stosowałem podobną konstrukcję ;p)
Super wpis! Dzięki wielkie, przyda mi się na pewno :)
Pozdrawiam.