Objective C ELTE IK Programozási paradigmák összehasonlítása II GY. Balog Szabolcs Dávid és Tóth Ádám
Objektív?! C?! Az Objective C teljesen objektumorientált nyelv, a C-re épül és a Smalltalk üzenetküldő rendszerét használja. A ’80-as évek elején fejlesztette ki Brad Cox és Tom Love Vékony réteg a C felett, C++ -ra hivatkozás történhet. A Mac OS X és az iOS operációs rendszerek fő programozási nyelve Windows alatt is használható, bár korlátozottan: A Cocoa framework portokra pl. vannak projektek Az Apple keretrendszereket nem használó kódok GCC-vel fordíthatók.
Hello World! #import <stdio.h> int main( int argc, const char *argv[] ) { printf(" Hello World!\n" ); return 0; } Ez még nagyon hasonlít egy C-s programra...
Beépített típusok char A character 1 byte int An integer — a whole number 4 bytes float Single precision floating point number Double Double precision floating point number 8 bytes short A short integer 2 bytes long A double short long long A double long BOOL Boolean (signed char)
Szintaxis alapok In general hasonló a C-hez (azért vannak különbségek is ) Preprocesszor direktívák #include helyett #import Változó deklaráció: <típus> <vnév> ; Függvénydefiníció: <láthatósági módosító> (visszatérési típus) <fnév> : <p1> : <p2> : .... : <pn> { <törzs> } Pl. – (void) setField : int value { }
Utasítások C alapú nyelvekhez hasonlóan. Értékadások: int x = 0; Osztályok esetén ha van ún. „getter/setter” függvényünk, akkor többféle lehetőség is adott myAppObject.theArray = aNewArray; [myAppObject setTheArray:aNewArray];
Függvények
Függvények (folytatás) Itt jön be a Smalltalk – Message rendszer [ <objektum neve> <függvény> ] Hogy ne kelljen lokális változókat tárolni a memóriában, az üzenetek egymásba ágyazhatóak, ezáltal megnövelve az Objective C-ben programozók agyvérzésének kockázatát.... Pl. [[myAppObject theArray] insertObject:[myAppObject objectToInsert] atIndex:0]; Ez még viszonylag egyszerű, de elsőre nagyon bántja a szemet ugye?
Pointerek Nem meglepő módon.... <típus> * <változónév> ** is létezik természetesen A pointerek ugyanúgy memóriacímeket tárolnak, így összegük, inkrementációjuk hasonló eredménnyel jár, mint C/C++ esetben Dereferálás a megszokott módon: *<pointernév> Felszabadítás: release/autorelease.... C++ értelemben vett referencia nincs, az már Objective C++....
Osztályok Minden osztály 2 fájlra bontható .h – header fájlok, itt található az osztály interfésze .m – implementáció Ez a hierarchia a C++ osztályfelépítését idézi. Minden objektum őse az NSObject ez a C# Object itteni megfelelője (id, mint anytype) Felsorolási típusok enum <név> { id1, id2, ..... , idn };
Osztályok - Header
Osztályok – Header 2 Minden header fájl egy @interface fordító direktívával indul és egy @end direktívával végződik Láthatósági módosítók @private @public @protected – alapbeállítás!!! A C alapú nyelvekben megszokott blokkba csak az osztály mezői kerülnek a függvény szignatúrák ezen kívülre ( - : osztálymetódus, + : publikus, ez az alapbeállítás a header fájlokon kívül ) Öröklődésről később....
Osztályok - Implementáció @implementation direktíva a fájl elején és @end a végén Ezek között helyezzük el a header fájlban deklarált függvényeink megvalósítását, ami a C++ -hoz hasonlóan történik. (PÉLDA!!)
Osztályok - Tulajdonságok @property ( < nonatomic/atomic>, <copy/retain/assign> ): <típus> <név> atomic az alapbeállítás, a lényege, hogy „értelmes” adatot kapunk olvasáskor akkor is, ha egy másik folyamat a tulajdonságot írni akarja (nem jelent kölcsönös kizárást, ezt másképp kell elérni). Bizonyos könyv szerint ritka, hogy az atomic használata indokolt lenne ráadásképp a nonatomic gyorsabb is..... Ha használjuk a @synthesize kulcsszót a „getter/setter” automatikusan generálódik (újabb llvm-ben ez alapbeállítás)
Osztályok – Tulajdonságok 2 assign: ezt nem pointer típusú adatok esetén használjuk, mivel egy sima értékadást jelent. retain: pointer típusú adatokhoz, ez visszatartást jelent, emiatt kézzel történő felszabadítás szükséges! copy: mutable objektumhoz. Manuális felszabadítás (release parancs)!
Osztályok használata Példányosítás : 2 lépéses művelet 1. Memória allokálása 2. Inicializálás Hogyan is néz ez ki? <típus> *e = [[<típus> alloc] init]; <típus> *myObject = [<típus> new]; Használható bármelyik, bár azt vegyük figyelembe, hogy a new nem támogatja az egyéni inicializálókat (pl. initWithString) A new egyébként egy osztályművelet, amit az NSObject implementál, OS X 10.0 felett használható
Öröklődés Ismerős módon @interface InheritedClass : BaseClass { .... } .... @end Az @implementation ..... @end részben kiegészítjük azokkal a funkciókkal, amikre szükségünk van, vagy felüldefiniálunk egy már létezőt. Többszörös öröklődés nincs, kompozícióval érhetünk el hasonló hatást.
Protokollok C# - os interfészeknek megfelelőek. @property <név> fg1, fg2,fg3.......,fgn @end Lehetnek opcionális függvények is, ez a megérzésnek megfelelőt jelenti, azaz implementációjuk nem kötelező. Alapértelmezett beállítás: kötelező. @optional fg1,fg2,.... @end/másik direktíva pl. @required Az opcionális függvények használatakor ellenőriznünk kell, hogy implementálták-e, ez szelektorhasználattal megoldható.
Protokollok 2 Példa az IProtocol (minden használt név csupán szemléltető célt szolgál) használatára egy osztályban: @interface A : B, <IProtocol> Nem kell újra deklarálni a függvényeket az osztályban. Több protokoll használata esetén pl: @interface A: B, <IProtocol, IClass, IDontKnowWhatImDoing> A protokollok származhatnak is egymásból. Pl. @protocol IProtocol <NSObject> ......
Felüldefiniálás/Túlterhelés Operátor túlterhelés nincs! Függvény túlterhelés sincs, bár trükkökkel elérhető valami hasonló: Külön nevet kell használni, de a függvény nevébe beletartoznak a paraméternevek is -(void) writeToFile:(NSString *)path fromInt:(int)anInt; -(void) writeToFile:(NSString *)path fromString:(NSString *) aString; Egy ősosztály függvénye felüldefiniálható, de bizonyos szabályokat be kell tartanunk 1. Pontosan annyi és olyan típusú argumentuma lehet az új függvénynek, mint az eredetinek 2. Visszatérési értékben sem lehet eltérés!
Virtuális függvények Ez sincs... Valójában minden Objective C függvény virtuális (melyik függvény kerül meghívásra kérdésre futásidőben történik válaszadás) Ha van egy A és egy B osztályunk (B legyen A leszármazottja) és mindkettőnek van egy method nevű függvénye, akkor pl. Megfelelő pointerezéssel elérhetjük, hogy a leszármazott osztály függvénye kerüljön meghívásra. A* obj = [[B alloc] init]; [obj method]; // B implementációja kerül meghívásra
Hasznos Linkek/Források www.google.com www.stackoverflow.com https://developer.apple.com/library/mac/#referencelibrary/GettingStarted/Learning_Objective-C_A_Primer/
Köszönöm a figyelmet!