De andra två pelarna i OOP
Som jag nämnde i det första inlägget i den här serien, kommer du ofta att höra om objektorienterad programmerings tre pelare. Du kanske också hör om The Four Pillars of Object-Oriented Programming.
Och det är inte så att det är totalt sju eller något liknande. Istället handlar det mer om vad folk anser vara grundläggande för OOP: Finns det tre eller fyra stora koncept?
Du kan ana från föregående artikel (låt vara titeln), jag tror att det finns fyra.
Och i det här inlägget kommer jag att täcka de två sista:
- Arv,
- och polymorfism
Om du har gjort någon typ av objektorienterad programmering innan du läste den här artikeln, har du förmodligen hört talas om åtminstone en av dessa.
Oavsett, låt oss ta en titt på var och en av dem mer detaljerat.
Ytterligare två pelare i OOP
Innan jag går in på var och en av dessa vill jag vara säker på att du är med om vad vi hittills har täckt.
Ett ord om analys
Jag ska inte förtydliga poängen, men hela anledningen till att jag nu talar om objektorienterade grunder är för att vi går in i en annan fas av detta material. Vi började med att täcka analysfasen som inkluderade:
Nu till utveckling
Och nu är vi vidare till utvecklingsfasen. Vissa kanske kallar det fundamentals (men jag tycker att du inte kan göra bra utveckling utan grunderna så det finns det(.
Om du inte har läst det tidigare inlägget rekommenderar jag att du gör det innan du fortsätter eftersom det täcker begreppen abstraktion, inkapsling och hur det relaterar till WordPress.
3 Arv
Begreppet arv är ganska lätt att följa. Det vill säga, en klass kan ärva attribut från en annan klass. Jag ska ge några exempel på detta om ett ögonblick, men låt mig ge en fungerande definition för syftet med detta inlägg:
Arv hänvisar till idén att en klass, även om den har sin egen impementering, bokstavligen ärver egenskaper, funktioner och allmän implementering från en överordnad klass.
Exempel 1: Ett dokument
I mycket enkla termer, låt oss säga att du har en klass som heter Dokument och ett dokument har en titel och det har innehåll. Sedan finns det en underklass av dokument som har attribut för ett datum och en tid. Vi skulle kunna kalla detta ett PostDocument eller ett PageDocument.
Det vill säga, PageDocument ärver dokumentets egenskaper och attribut samtidigt som det lägger till sin egen implementering till det. Vettigt?
Om inte, oroa dig inte. Det "klickar" inte alltid i början så låt oss titta på ett annat exempel.
Exempel 2: Ett meddelande
Låt oss säga att vi har en meddelandeklass. Ett meddelande har vanligtvis två egenskaper:
- 1 en avsändare,
- 2 En mottagare.
Det är rättvist att säga att det finns olika typer av meddelanden, eller hur? Det vill säga, kanske har vi ett e-postmeddelande eller kanske vi har ett textmeddelande.
Ett e-postmeddelande har fortfarande en avsändare och har fortfarande en mottagare men det har så mycket mer, eller hur? Den har saker som:
- en ämnesrad,
- en valfri bilaga,
- en annan uppsättning avsändare som den skickas till,
- stöd för att kopiera andra till meddelandet offentligt eller privat,
- och mycket mer.
Ett textmeddelande å andra sidan har inte nödvändigtvis allt ovanstående. Låt oss anta att vi pratar om ett grundläggande SMS-meddelande (mot ett rikt textmeddelande i något som Hangouts, Telegram, iMessage eller vad som helst som finns där ute).
Denna klass kommer att:
- vara bunden till ett telefonnummer,
- kan inkludera en grupp andra mottagare som alla är offentliga,
- en operatör (det vill säga en mobilleverantör),
- ett maximalt antal tecken som den kan innehålla
- möjligheten att dela upp ett enda meddelande i flera meddelanden om det maximala antalet tecken överstiger ett visst antal tecken.
Men det väcker fortfarande frågor om egenskaper och metoder (eller, mer generellt, implementering, eller hur?)
Ett ord om implementering
När det kommer till objektorienterad programmering har vi vad vi kallar åtkomstmodifierare. Du kanske har läst dem på annat håll som kallas för synlighetsmodifierare eller något liknande.
Allt är samma.
Kort sagt kan dessa modifierare definieras som:
Nyckelord som styr vad andra klasser har tillgång till informationen till hands.
Lyckligtvis är den här delen enkel att förstå:
- privata egenskaper och funktioner är endast tillgängliga för den klass där de är definierade. Det betyder att PostDocument inte kan använda något i Dokument som är markerat som privat. PostDocument är för all del inte ens medveten om att denna information finns.
- skyddade egenskaper och funktioner är tillgängliga för klassen där de är definierade och alla klasser som är en avkomling. Det vill säga alla klasser som ärver data från basklassen eller förälderklassen har tillgång till den. Så, till skillnad från privata implementeringsdetaljer, kan PostDocument komma åt information från Document om det är markerat som skyddat.
- offentliga fastigheter och funktioner är tillgängliga för alla. Detta har egentligen ingenting med arv att göra, utan mer med inkapsling, om något. Istället handlar det om att bestämma vad vi vill att andra objekt ska få tillgång till.
Så hur hanteras implementeringen? Detta varierar från språk till språk, men PHP stöder inte det som kallas "multipelt arv." Enkelt uttryckt kan en given klass i PHP bara ärva (eller utöka) en annan klass. Inte flera klasser (vissa språk stöder detta).
När du utökar en klass, ärver underklassen alla offentliga och skyddade metoder från den överordnade klassen. Om inte en klass åsidosätter dessa metoder kommer de att behålla sin ursprungliga funktionalitet.
I vårt exempel kan vi inte introducera en annan klass som WrittenDocument som ärver från PageDocument såväl som PostDocument. Det är antingen det ena eller det andra. Och det är värt att notera att om det ärver från PostDocument så ärver det också information från Document eftersom det är en underklass till en underklass av en klass.
4 Polymorfism
Nu när vi har en grundläggande definition av arv på plats, kan vi prata om polymorfism. Den goda nyheten är att det är ett stort, konstigt ord för ett väldigt enkelt koncept.
Den dåliga nyheten är att vi inte har pratat om gränssnitt eller abstrakta klasser. Dessa kommer men de anses vara en del av de fyra pelarna, så oroa dig inte för dem just nu.
Tänk istället på det så här:
Polymorfism tillåter oss att referera till en klass av en typ när den kan deklareras som en annan typ.
Det kan fortfarande vara förvirrande, men kommer du ihåg vårt, säg, meddelandeexempel ovan? Vi kan instansiera en SMSMessage-klass som utökar Message-klassen och sedan anropa vissa metoder på den.
SMSMessage kan ha en metod som Message-klassen har. Och om klassen har instansierats som en instans av klassen SMSMessage, kommer den att anropa den metoden. På liknande sätt, om den inte har en metod men dess överordnade klass, Message, har det, kommer den att anropa den metoden.
Ibland är det lättast att förstå detta i kod så låt oss göra det.
Låt oss först definiera vår meddelandeklass :
<?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";
}
}
Låt oss sedan definiera vår SMSMessage- klass. Observera att den inte har en receive() funktion. Detta kommer att vara viktigt för en stund:
<?php
class SMSMessage extends Message
{
public function send()
{
echo "This message is sent from the SMSMessage class.n";
}
}
Låt oss nu instansiera vår Message -klass och anropa några metoder:
<?php
$message = new Message();
$message->send();
$message->receive();
Och låt oss göra samma sak med klassen SMSMessage:
<?php
$message = new SMSMessage();
$message->send();
$message->receive();
Om du vill ha hela skriptet kan du se det här, ladda ner det och köra det lokalt.
Arv, polymorfism och WordPress
Här är take away (och vi kommer att utforska detta mer när vi kommer in på gränssnitt och abstrakta klasser): När en klass utökar en annan klass och den inte har de implementeringsdetaljer som dess överordnade klass har, kommer förälderns implementering att användas.
Ett annat sätt att tänka på det är "att arbeta upp kommandokedjan." Det börjar med den klass som är lägst till vad vi har skapat. I vårt exempel ovan är det SMSMessage. Om den inte hittar den där kommer den att flytta upp till den klass den utökar. (Och om den inte hittar den där och den klassen utökar en klass, kommer den att försöka där.)
Hela det polymorfa är detta: Vi har instansierat en klass av en typ, SMSMessage, men den använder implementeringen av en klass av en annan typ (som den ärver, ja, men det är ändå annorlunda).
Skrivkurser på WordPress
Slutligen skulle jag vilja lämna er med detta: Jag har nämnt något liknande detta i förra inlägget men jag vill upprepa det här.
Oavsett hur många av dessa begrepp WordPress core använder spelar det ingen roll eftersom vi kan skriva högkvalitativ, objektorienterad kod på WordPress som interagerar med WordPress och som spelar bra med WordPress (och annan tredjepartskod – inte alltid, men många gånger).
Vad händer härnäst?
Därefter kommer vi att titta på gränssnitt och abstraktioner.
Dessa är fortfarande grundläggande för objektorienterad programmering, men om du har förstått de två föregående inläggen är du redo för en gedigen upplevelse av de kommande koncepten.
Och om inte, oroa dig inte! Du kan alltid prata om det i kommentarerna eller så kan vi chatta om det mer via e-post.