Jak wspomniałem w pierwszym poście z tej serii, często będziesz słyszał o Trzech Filarach Programowania Obiektowego. Możesz także usłyszeć o czterech filarach programowania obiektowego.
I nie chodzi o to, że jest ich w sumie siedem czy coś takiego. Zamiast tego chodzi bardziej o to, co ludzie uważają za fundamentalne dla OOP: Czy istnieją trzy lub cztery główne koncepcje?
Jak można się domyślić z poprzedniego artykułu (nie mówiąc już o tytule), uważam, że są cztery.
A w tym poście omówię dwie ostatnie:
- Dziedzictwo,
- i polimorfizm
Jeśli przed przeczytaniem tego artykułu wykonywałeś programowanie obiektowe, prawdopodobnie słyszałeś o co najmniej jednym z nich.
Niezależnie od tego przyjrzyjmy się każdemu z nich bardziej szczegółowo.
Dwa kolejne filary OOP
Zanim wskoczę do każdego z nich, chcę się upewnić, że jesteś uwikłany w to, co do tej pory omówiliśmy.
Słowo o analizie
Nie będę omawiał tego tematu, ale cały powód, dla którego teraz mówię o podstawach zorientowanych obiektowo, jest taki, że przechodzimy do innej fazy tego materiału. Zaczęliśmy od omawiania fazy analizy, która obejmowała:
Teraz do rozwoju
A teraz jesteśmy w fazie rozwoju. Niektórzy mogą nazwać to podstawami (ale cieszę się, że nie można zrobić dobrego programowania bez podstaw, więc jest to (.
Jeśli nie czytałeś poprzedniego posta, polecam to zrobić przed kontynuowaniem, ponieważ omawia on pojęcia abstrakcji, enkapsulacji i ich związku z WordPress.
3 Dziedziczenie
Pojęcie dziedziczenia jest dość łatwe do naśladowania. Oznacza to, że jedna klasa może dziedziczyć atrybuty innej klasy. Za chwilę podam kilka przykładów, ale pozwólcie, że podam roboczą definicję na potrzeby tego postu:
Dziedziczenie odnosi się do idei, że jedna klasa, chociaż ma własną implementację, dosłownie dziedziczy właściwości, funkcje i ogólną implementację z klasy nadrzędnej.
Przykład 1: Dokument
Mówiąc bardzo prosto, załóżmy, że masz klasę o nazwie Document, a dokument ma tytuł i treść. Następnie istnieje podklasa dokumentu, która ma atrybuty daty i godziny. Możemy nazwać to PostDocument lub PageDocument.
Oznacza to, że PageDocument dziedziczy właściwości i atrybuty Document, jednocześnie dodając do niego własną implementację. Ma sens?
Jeśli nie, nie martw się. Na początku nie zawsze „klika", więc spójrzmy na inny przykład.
Przykład 2: Wiadomość
Powiedzmy, że mamy klasę Message. Wiadomość ma zazwyczaj dwie właściwości:
- 1 Nadawca,
- 2 Odbiorca.
Można jednak powiedzieć, że istnieją różne rodzaje wiadomości, prawda? To znaczy, być może mamy wiadomość e-mail, a może mamy wiadomość tekstową.
Wiadomość e-mail nadal ma nadawcę i odbiorcę, ale ma o wiele więcej, prawda? Ma takie rzeczy jak:
- temat,
- opcjonalny załącznik,
- inny zestaw nadawców, do których jest wysyłany,
- wsparcie dla kopiowania innych do wiadomości publicznie lub prywatnie,
- i wiele więcej.
Z drugiej strony TextMessage niekoniecznie będzie zawierał wszystkie powyższe elementy. Załóżmy, że mówimy o podstawowej wiadomości SMS (w przeciwieństwie do bogatej wiadomości tekstowej w czymś takim jak Hangouts, Telegram, iMessage lub cokolwiek innego).
Ta klasa będzie:
- być przywiązanym do numeru telefonu,
- może obejmować grupę innych odbiorców, z których wszyscy są publiczni,
- operator (czyli operator komórkowy),
- maksymalna liczba znaków, które może zawierać
- możliwość podzielenia pojedynczej wiadomości na wiele wiadomości, jeśli maksymalna liczba znaków przekracza określoną liczbę znaków.
Ale wciąż rodzi pytania dotyczące właściwości i metod (lub ogólniej implementacji, prawda?)
Słowo o wdrożeniu
Jeśli chodzi o programowanie obiektowe, mamy coś, co nazywamy modyfikatorami dostępu. Być może czytałeś je gdzie indziej jako, powiedzmy, modyfikatory widoczności lub coś w tym stylu.
To wszystko jest takie samo.
W skrócie te modyfikatory można zdefiniować jako:
Słowa kluczowe, które kontrolują dostęp innych klas do dostępnych informacji.
Na szczęście ta część jest łatwa do zrozumienia:
- prywatne właściwości i funkcje są dostępne tylko dla klasy, w której są zdefiniowane. Oznacza to, że PostDocument nie może używać w dokumencie niczego, co jest oznaczone jako prywatne. Dla wszystkich intencji i celów PostDocument nie jest nawet świadomy, że te informacje istnieją.
- chronione właściwości i funkcje są dostępne dla klasy, w której są zdefiniowane, i każdej klasy, która jest potomkiem. Oznacza to, że każda klasa, która dziedziczy dane z klasy bazowej lub klasy nadrzędnej, ma do nich dostęp. Tak więc, w przeciwieństwie do prywatnych szczegółów implementacji, PostDocument może uzyskać dostęp do informacji z dokumentu, jeśli jest oznaczony jako chroniony.
- właściwości i funkcje publiczne są dostępne dla każdego. Tak naprawdę nie ma to nic wspólnego z dziedziczeniem, ale raczej z enkapsulacją, jeśli w ogóle. Zamiast tego chodzi o decydowanie, do czego chcemy, aby inne obiekty miały dostęp.
Jak więc przebiega wdrożenie? Różni się to w zależności od języka, ale PHP nie obsługuje tak zwanego „wielokrotnego dziedziczenia”. Mówiąc najprościej, dana klasa w PHP może dziedziczyć (lub rozszerzać) tylko jedną inną klasę. Nie wiele klas (niektóre języki to obsługują).
Kiedy rozszerzasz klasę, podklasa dziedziczy wszystkie publiczne i chronione metody z klasy nadrzędnej. O ile klasa nie zastąpi tych metod, zachowają one swoją pierwotną funkcjonalność.
W naszym przykładzie nie możemy wprowadzić innej klasy, takiej jak WrittenDocument, która dziedziczy zarówno po PageDocument, jak i PostDocument. To albo jedno, albo drugie. I warto zauważyć, że jeśli dziedziczy z PostDocument, dziedziczy również informacje z Document, ponieważ jest to podklasa podklasy klasy.
4 Polimorfizm
Teraz, gdy mamy już podstawową definicję dziedziczenia, możemy mówić o polimorfizmie. Dobrą wiadomością jest to, że jest to duże, dziwne słowo na bardzo prostą koncepcję.
Zła wiadomość jest taka, że nie rozmawialiśmy o interfejsach ani klasach abstrakcyjnych. Nadchodzą, ale są uważane za część czterech filarów, więc nie martw się nimi teraz.
Zamiast tego pomyśl o tym w taki sposób:
Polimorfizm pozwala nam odnosić się do klasy jednego typu, kiedy może być zadeklarowana jako inny typ.
Nadal może to być mylące, ale pamiętasz nasz, powiedzmy, przykład wiadomości powyżej? Możemy utworzyć instancję klasy SMSMessage, która rozszerza klasę Message, a następnie wywołać na niej określone metody.
SMSMessage może mieć metodę, którą ma klasa Message. A jeśli klasa została utworzona jako instancja klasy SMSMessage, wywoła tę metodę. Podobnie, jeśli nie ma metody, ale ma ją klasa nadrzędna Message, to wywoła tę metodę.
Czasami najłatwiej jest to zrozumieć w kodzie, więc zróbmy to.
Najpierw zdefiniujmy naszą klasę Message :
<?php
class Message
{
public function send()
{
echo "This message is sent from the Message class.n";
}
public function receive()
{
echo "This message was received from the Message class.n";
}
}
Następnie zdefiniujmy naszą klasę SMSMessage. Zauważ, że nie ma funkcji receive(). To będzie ważne chwilowo:
<?php
class SMSMessage extends Message
{
public function send()
{
echo "This message is sent from the SMSMessage class.n";
}
}
Teraz stwórzmy instancję naszej klasy Message i wywołajmy kilka metod:
<?php
$message = new Message();
$message->send();
$message->receive();
I zróbmy to samo za pomocą klasy SMSMessage:
<?php
$message = new SMSMessage();
$message->send();
$message->receive();
Jeśli chcesz cały skrypt, możesz go zobaczyć tutaj, pobrać i wykonać lokalnie.
Dziedziczenie, polimorfizm i WordPress
Oto wniosek (omówimy to bardziej, gdy przejdziemy do interfejsów i klas abstrakcyjnych): Kiedy klasa rozszerza inną klasę i nie ma szczegółów implementacji, które posiada jej klasa nadrzędna, zostanie użyta implementacja rodzica.
Innym sposobem myślenia o tym jest „opracowanie łańcucha dowodzenia”. Zacznie się od klasy najniższej do tego, co stworzyliśmy. W naszym przykładzie powyżej jest to SMSMessage. Jeśli go tam nie znajdzie, przeniesie się do klasy, którą rozszerza. (A jeśli go tam nie znajdzie, a ta klasa rozszerzy klasę, spróbuje tam.)
Cała polimorficzna rzecz jest następująca: utworzyliśmy instancję klasy jednego typu, SMSMessage, ale używa ona implementacji klasy innego typu (która dziedziczy, tak, ale to jednak inne).
Pisanie zajęć na WordPressie
Na koniec chciałbym zostawić tobie to: wspomniałem o czymś podobnym w poprzednim poście, ale chcę to powtórzyć tutaj.
Niezależnie od tego, ile z tych koncepcji wykorzystuje rdzeń WordPress, nie ma to znaczenia, ponieważ możemy na WordPressie pisać wysokiej jakości, obiektowy kod, który współdziała z WordPressem i dobrze współpracuje z WordPressem (i kodem innych firm – nie zawsze, ale wiele razy).
Co dalej?
Następnie przyjrzymy się interfejsom i abstrakcjom.
Są one nadal podstawą programowania obiektowego, ale jeśli zrozumiałeś poprzednie dwa posty, jesteś przygotowany na solidne doświadczenie z nadchodzącymi koncepcjami.
A jeśli nie, nie martw się! Zawsze możesz o tym porozmawiać w komentarzach lub możemy porozmawiać o tym więcej przez e-mail.