Välkommen till del tre av denna serie -Jag hoppas du njuter av det! I förra veckan tittade vi på hur vi separerar klasser i separata filer (gränssnitt och implementering), denna vecka kommer vi att titta på klasser igen, men lite mer djupgående. Vi tar också en topp i arv och hur det fungerar, tillsammans med varierande räckvidd.
Hittills har vi fått bra feedback via e-post, twitter och kommentarer. Det är kul att se så många människor är intresserade av detta ämne och det är ännu bättre att se så många av dig själv försöker ut det och frågar några bra frågor. Fortsätt så!
Låt oss granska vad vi har lärt oss om klasserna i denna serie hittills. Om du inte vet något av det här, kan du skumma tillbaka till den sista handledningen för att återskapa. Ok, så, vad är klasser?
En klass är en samling inkapslade data och anpassade metoder. En klass kan innehålla många olika typer av data, och klassmetoderna utför vanligtvis (men inte alltid) åtgärder relaterade till den data. I mål-C är en klass vanligen sammansatt av två filer: en gränssnittsfil och en implementeringsfil. Gränssnittsfilen använder .h-filtillägget enligt konventionen och är där den person som använder klassen snabbt kan hitta metoder och datamedlemmar som är tillgängliga för klassen. Implementeringsfilen använder .m filtillägg enligt konvention och är där majoriteten av koden finns eftersom den innehåller det faktiska genomförandet av alla funktioner som deklareras i gränssnittet.
Så, vad gör en klass annorlunda än ett objekt? Vad är ett objekt? Ett objekt är en förekomst av en klass. Tänk tillbaka till vårt exempel med bilen i den sista delen av serien. Var bil är klassen då min bil, dansCar, och din bil skulle alla vara föremål för att de är fall av bilklassen.
Innan vi fortsätter vill jag dela några (av många) vanliga klasser du kommer att använda mycket som tillhandahålls av Apple, men först en snabb historielektion.
Många klasser Apple tillhandahåller är prepended med förkortningen "NS", som står för NextStep. När Steve Jobs lämnade Apple grundade han NeXT och skapade arbetsstationens datorer som sprang på sitt operativsystem. Objektorienterat programmeringsspråk som används på dessa maskiner kallades NeXTSTEP, vilket är var vi får "NS" från. När Apple "förvärvades" (en annan historielektion i sig) NeXTSTEP, bestämde de sig för att basera Mac OS X på NeXTSTEP.
Här är några enkla, vanliga klasser vi ser mycket av:
Vi kommer att lära oss många senare, men för nu kommer ovanstående att vara till nytta. Du undrar förmodligen vilka mutable och oföränderliga medel som är en helt rimlig fråga. Om ett objekt är oföränderlig det betyder att när vi skapar objektet och tilldelar ett värde så är det statiskt. Värdet kan inte ändras. Om ett objekt är föränderlig då är det dynamiskt, vilket betyder att värdet kan ändras efter skapandet.
Låt oss säga att vi vill skapa en statisk textsträng och logga in, hur skulle vi göra det? I vår kod skulle det se ut så här:
#importeraint main (int argc, const char * argv []) NSString * testString; testString = [[NSString alloc] init]; testString = @ "Här är en teststräng i testString!"; NSLog (@ "testString:% @", testString); returnera 0;
Jag skapade den här filen i XCode genom att gå till Arkiv> Nytt projekt> Mac OS X> Program> Kommandoradsverktyg> Typ: Stiftelse (ganska en resa!) och redigera filen implementation (extension: .m) i projektet.
Det finns en hel del saker här som är nya, så låt oss undersöka ovanstående bit för bit.
Först och främst importerar vi grundbiblioteket (det här beror på att vi sätter typ till Foundation i det nya projektfönstret innan).
int main (int argc, const char * argv [])
Detta förklarar den inledande funktionen som kommer att ringas när vårt program börjar utföras. De två parametrarna separerade av ett kommatecken är för att överföra argument till vår ansökan. För tillfället oroa dig inte för dessa eftersom vi inte behöver dem just nu.
NSString * testString; testString = [[NSString alloc] init];
Vi skapar nu en pekare till ett NSString-objekt som heter testString. När den första raden av detta är klar finns det ingen sträng ännu, bara en pekare till en sträng som vi ännu inte har skapat. På nästa rad skapar vi strängen som pekaren pekar på.
Vi kunde alternativt ha skrivit den sista raden så här;
testString = [NSString allokering]; [testString init];
Det kan tyckas lite förvirrande först. I den första versionen har vi nestat uttalandena inom parentes på samma rad, medan i det andra har vi separerat uttalandena i två linjer. Metoden init initierar alla instansvariablerna i klassen.
testString = @ "Här är en teststräng i testString!";
Denna rad är ganska självförklarande, anledningen till att vi lägger ut citat med ett @ -tecken är att berätta för kompilatorn att följande text är en NSString.
NSLog (@ "testString:% @", testString);
Här loggar vi lite information till konsolen. XCode har en debugger inbyggd som du hittar under menyn Kör. Det är väldigt användbart när du utvecklar en applikation för att logga när händelser händer och värdena för vissa variabler - det kan hjälpa till vid felsökning av dina program och felsökningsproblem. Den här metoden fungerar som printf (kom ihåg den första veckan?) Där vi levererar en sträng text med ett ersättnings tecken (% @ betyder ett objektiv-C-objekt).
Slutligen returnerar vi 0, vilket vi vet bara berättar operativsystemet att applikationen slutade utan problem.
Kom ihåg när vi gjorde vår NSString tidigare, använde vi init-metoden? Tja NSMutableString, NSArray och faktiskt, varje enskild NS klass, använder också init. Verkar mycket bortkastad kod för att sätta init-metoden i varje klass, eller hur? Det är därför init initieras vanligen bara en gång i rotklassen som kallas NSObject. Eftersom klasser ärva från varandra, en klass som skapas som ett barn till en annan, kommer föräldraklassen automatiskt att få tillgång till moderklassmetoderna.
Låt oss ta NSMutableString till exempel. NSMutableString har NSString för en förälder (gör det till ett barn), vilket betyder att det ärar från NSString. Under tiden. NSString har NSObject som förälder, så det ärver från NSObject.
Så till exempel har NSObject en metod som heter init, så varje underklass har denna metod implementerad - som kallas en klassmetod. Faktum är att init-metoden i NSObject faktiskt inte gör någonting, det returnerar helt enkelt sig själv. Anledningen till detta är att metoder kan skrivas över. Så NSArray-klassen kan åsidosätta init som den ärver för att lägga till funktionalitet till det - till exempel att se till att minnet är tillgängligt eller förbereda eventuella instansvariabler som det kan behöva.
Som visat är detta användbart eftersom det innebär att förutom att arva från klasser kan vi också förlänga klasserna. När vi utökar en klass tar vi en befintlig klass och lägger till ytterligare funktionalitet till det som redan är tillgängligt. Det innebär att du kan skapa din egen version av NSString med ytterligare metoder, till exempel en metod för att fylla strängen med slumpmässig text eller utföra någon form av teckenkodning.
Vid denna tidpunkt bör grunden för hur klasserna fungerar vara tydliga. För att testa din förståelse, se om du kan svara på följande frågor i ditt sinne:
Eftersom klasser är en så viktig del av mål-C, är det viktigt att verkligen trivas med dem. Förra veckan började vi titta på lektioner och denna vecka har vi gått in på djupet. Nästa vecka kan du vara glad att höra, vi kommer att flytta bort från teoretiska sidan och börja arbeta med vår egen enkla klass eller två för att utföra enkla uppgifter.
Eftersom vi huvudsakligen har gjort teori hittills, är din läxa i veckan att surfa Apples utvecklarwebbplats (du borde ha gjort det här förra veckan) och titta på några av de tillgängliga klasserna. Om du inte vet var du ska börja, börja med något som NSString. Du blir bekvämare med detaljerna i förälderklassen, metoderna och så vidare. Detta kommer att vara viktigt senare när du använder klasser utanför denna serie och du vill veta vilka metoder de ärva eller använda.
Vi kommer bli mer praktiska nästa vecka med lite klasskodning. Klasser är verkligen centrala för Objective-C, så det är mycket viktigt att du tar tag i dem och målet med denna serie är att verkligen se till att du gör!
Som vanligt, om du har några frågor eller kommentarer, kan du nå mig genom att släppa en kommentar eller e-post. Om du vill ta kontakt med mig personligen och få ett snabbt svar, skicka mig en tweet!