Přejít k navigační liště

Zdroják » Různé » Základy Objective-J: syntaxe a framework Foundation

Základy Objective-J: syntaxe a framework Foundation

Články Různé

V minulém díle jsme se podívali na to, co to je Objective-J a Cappuccino z obecného hlediska, a také jsme si připravili pracovní prostředí pro vývoj. V dnešním díle se podíváme detailněji na syntaxi Objective-J a začneme postupně procházet celé Cappuccino a jeho jednotlivé části.

Objective-J

Jak již z minula víme, Objective-J je programovací jazyk vyvinutý jako součást frameworku Cappuccino a svou syntaxí je téměř identický s Objective-C. Snaží se do Javascriptu vnést zvyky z programování desktopových aplikací – třídy, dědičnost, import souborů, apod. Objective-J se může do JavaScriptu překládat až za běhu aplikace nebo se dá předem zkompilovat. Tak, to by nám pro stručné zopakování mohlo stačit a můžeme se do jazyka pustit trochu podrobněji.

Třídy

V Objective-J najdeme 2 typy objektů, prvním jsou nativní JavaScriptové objekty a tím druhým jsou Objective-J objekty. Jak již bylo zmíněno v předchozím článku, Objective-J stále zůstává obyčejným JavaScriptem, takže pokud napíšeme jakýkoliv kód v čistém JavaScriptu, je validním kódem i v Objective-J. Pokud s vývojem teprve začínáme a známe základní koncept OOP, nemělo by pro nás být Objective-J složité. Znalost Objective-C je určitě výhodou.

Pojďme si nyní napsat jednoduchou třídu (zatím bez testování) a ukázat si na ní základní princip syntaxe Objective-J.

@import <Foundation/CPObject.j>
@implementation Monstrum : CPObject
{
    CPString name;
}
//metody
@end

Na prvním řádku @import <Foundation/CPObject.j> importujeme třídu CPObject z frameworku Foundation (budeme detailněji rozebírat níže). V Objective-J máme 2 typy importu souborů, první s úhlovými závorkami (v příkladu) importuje kód z již existujícího frameworku, kdežto @import "Monstrum.j" slouží k importování lokálních souborů naší aplikace.

Jak již z minula víme, každá třída začíná klíčovým slovem @implementation, za ním následuje název naší třídy Monstrum a dvojtečka, za kterou je třída, od které ta naše dědí. V tomto případě je to třída CPObject, která obsahuje ty nejzákladnější metody a většina námi napsaných tříd od ní bude dědit. Mezi složenými závorkami se nachází všechny instanční proměnné CPString name. Deklarace těchto proměnných je důležitá, protože při jejich nepoužití se automaticky ze všech proměnných stanou proměnné globální. Za uzavírající závorku pak budeme psát všechny metody a celá třída je ukončena klíčovým slovem  @end.

Metody

Stejně jako je tomu u objektů, můžeme použít standardní JavaScriptové funkce nebo si můžeme implementovat vlastní metody za pomocí Objective-J. Metoda může začínat znakem plus (+), který nám říká, že jde o metodu statickou nebo znakem minus (-), který značí metodu instanční, dále pokračuje návratovým datovým typem v závorkách (v příkladu void  – procedura), název metody, dvojtečka která odděluje název metody a datový typ prvního argumentu, který je vložen do proměnné  aName.

- (void)setName:(CPString)aName
{
    name = aName;
}

Velmi důležité jsou v Objective-J metody s více argumenty. Zde je definice jednoduché metody, která přiděluje jméno konkrétnímu monstru: 

- (void)setName:(CPString)aName forMonstrum:(id)aMonstrum
{
    //metoda s dvěma pojmenovanými argumenty
    //můžeme uložit jméno konkrétního monstra
}

Pojďme si tuto metodu rozebrat trochu podrobněji. Začátek je stejný jako u metody předchozí, jedná se tedy o instanční metodu, která nic nevrací - (void)setName a jako první argument přijímá objekt typu CPString a jeho obsah při zavolání metody vkládá do proměnné  aName.

Objective-J se od JavaScriptu odlišuje tím, že od Objective-C přebírá pojmenované argumenty. forMonstrum je tedy název samotného argumentu, (id) je univerzální datový typ, který se používá pokud předem nevíme, jaký typ objektu budeme zpracovávat nebo má metoda za úkol zpracovávat více typů objektů. Celá definice metody končí opět proměnnou aMonster, do které se vloží obsah argumentu při zavolání metody.

Metody již máme nadefinované, zbývá nám si vysvětlit syntaxi, kterou se zprávy objektům posílají:

[myMonstrum setName: @"SEO odborník"];
[monstrumCollection setName: @"SEO odborník" forMonstrum: myMonstrum];

Na prvním řádku posíláme zprávu setName objektu myMonstrum, tato zpráva způsobí vyvolání metody setName a nastaví jméno daného objektu. Pokud jste se doposud nesetkali se syntaxí Objective-C nebo Objective-J, pravděpodobně přemýšlíte nad tím, co by mohl znamenat ten zavináč před textovým řetězcem. Je to konvence převzatá z frameworku Cocoa, kde zavináč před řetězcem znamená, že bude automaticky vytvořen jako objekt NSString a ne jako obyčejný string jazyka C. U Objective-J zavináč můžeme a nemusíme použít, je to jen převzatá konvence zápisu.

Kód na druhém řádku posílá zprávu objektu monstrumCollection (např. sbírka všech našich monster), ta nastaví jméno konkrétního monstra, které jí předáme v druhém argumentu.

Objekty

Objekt můžeme instanciovat zasláním dvou zpráv třídě Monster (viz box Rozdíl mezi zasláním zprávy a voláním metody). Metoda alloc je podobná klíčovému slovu New v jiných programovacích jazycích a metoda init je obdobou konstruktoru. Napsání vlastní init metody si ukážeme v některém z následujících dílů, zatím nám bude stačit základní inicializace.

Rozdíl mezi zasláním zprávy a voláním metody

Terminologie většiny objektově orientovaných jazyků, které se používají na webu, používá výraz „volání metody“, který je ale podle principů OOP chybný, či přinejlepším nepřesný. OOP nedovoluje přímo volat metodu, ale zná mechanismus zasílání zpráv (pokud znáte Smalltalk a odvozené jazyky, je vám tato terminologie důvěrně známa). Na základě této zprávy se v protokolu zpráv nalezne příslušná metoda, a ta se spustí. Spojení „volání metody“ není tedy zcela přesné, mělo by se hovořit o „vyvolání metody na základě zaslané zprávy“, ale běžně se používá. V tomto seriálu se ale přidržíme terminologie, používané v Objective-C (i Objective-J) a budeme hovořit o zasílání zpráv.

Při práci s objekty bude užitečné klíčové slovo self, které je ekvivalentem this v JavaScriptu.

var myMonstrum = [[Monstrum alloc] init];
[myMonstrum setName:"SEO odborník"];

Foundation

Framework Cappuccino se skládá z několika samostatných frameworků, toto dělení pochází z Cocoa. Základní dva frameworky, na které se v tomto seriálu zaměříme jsou Foundation a AppKit, který se stará o práci s uživatelským rozhraním.

Framework Foundation se stará o základní třídy, které nemají nic společného s uživatelským rozhraním (např. pole, stringy, čísla, apod.). V této části článku si projdeme a vyzkoušíme ty nejzákladnější, které se nám budou do budoucna při vývoji hodit. Začneme třídami CPString, CPArray, CPDictionary, CPData, CPDateCPNumber.

Nejjednodušší pro nás bude příklady testovat v čistém projektu, který jsme si minule vytvořili. V souboru AppController.j můžeme smazat vše, co zatím nebudeme potřebovat:

@import <Foundation/CPObject.j>
@implementation AppController : CPObject
{
}
- (void)applicationDidFinishLaunching:(CPNotification)aNotification //metoda se zavolá po dokončení spouštění aplikace
{
    var theWindow = [[CPWindow alloc] initWithContentRect:CGRectMakeZero() styleMask:CPBorderlessBridgeWindowMask],
        contentView = [theWindow contentView];
    [theWindow orderFront:self]; //pokud bychom smazali i Window, nepřestala by se aplikace načítat

    //
    //zde budeme psát kód, který chceme testovat
    //

    console.log("It works!"); //výpis do konzole prohlížeče
}
@end

CPString

Začněme třídou CPString. Všechny její metody můžeme nalézt v oficiální dokumentaci, nám bude pro začátek stačit inicializace s textovým řetězcem.

var text = [[CPString alloc] initWithString:@"mutant"];
console.log([text string]);

CPArray

Velmi důležitou částí Foundation je třída CPArray, která nám umožní pracovat s poli. Pro začátek si inicializujeme nové pole, vložíme do něj dva stringy a do konzole si vypíšeme obsah prvního a index druhého.

todo = [[CPArray alloc] init];
[todo addObject:@"Koupit rohlíky"];
[todo addObject:@"Napsat článek pro Zdroják"];
console.log([todo objectAtIndex: 0]); //"Koupit rohlíky"
console.log([todo indexOfObject: @"Napsat článek pro zdroják"]); //1

Pokud budeme s poli pracovat často, určitě nám přijde vhod objekt z pole také odstranit.

[todo removeObjectAtIndex:0];
console.log([todo objectAtIndex: 0]); //"Napsat článek pro zdroják"

Pro jednoduchou iteraci pole můžeme použít JavaScriptový cyklus  for:

for (var i = 0; i < todo.length; i++)
{
    console.log([todo objectAtIndex: i]);
}

CPDictionary

Třída CPDictionary nám slouží k ukládání hodnot typu klíč-hodnota. Všechny klíče jsou CPString a hodnoty libovolným Objective-J/JavaScript objektem.

var text = [[CPString alloc] initWithString:"ahoj"];
var number = [CPNumber numberWithBool:NO];
var keys = [CPArray arrayWithObjects:@"string", @"cislo", @"stringText", @"pole", nil];
var objects = [CPArray arrayWithObjects:@"test", number, text, todo, nil];
var dict = [CPDictionary dictionaryWithObjects:objects forKeys:keys];
[dict setObject:[CPNumber numberWithDouble:9.9] forKey:@"cislo2"];
[dict removeObjectForKey:@"string"];
console.log([dict objectForKey:@"stringText"]);
console.log([dict objectForKey:@"cislo2"]);

To by pro odzkoušení třídy CPDictionary mohlo pro začátek stačit (budeme s ní pracovat v dalších dílech seriálu více).

Další třídy

Posledními třídami, které bychom si pro začátek měli ukázat jsou: CPNumber, CPDate a CPData. Třída CPNumber slouží pro ukládání čísla v různých číselných formátech, na které jsme zvyklí. CPDate slouží pro uložení data v různých formátech a poslední třída CPData je wrapper pro jakýkoliv objekt Cappuccina.

var data = [CPData dataWithString:@"Cappuccino"];
var date = [CPDate date];
var number = [CPNumber numberWithDouble:17.0];
console.log(data); //vrací objekt, ve kterém je uložen string "Cappuccino"
console.log(date); //aktuální datum ve formátu: Fri Oct 15 2010 14:15:18 GMT+0200 (CEST)
console.log(number); //17.0

Co jsme se naučili

V druhém díle našeho seriálu o Cappuccinu jsme se naučili používat Objective-J a základní třídy frameworku Foundation. Příklady si můžete stáhnout na autorově webu: http://lukashu­rych.cz/zdrojak/tes­ts.zip

Co bude příště

Příští díl seriálu bude obsáhlejší a zaměříme se v něm na framework AppKit a práci s uživatelským rozhraním. Začneme psát vlastní jednoduchý todo list (aplikace, která bude konečně dávat smysl).

Komentáře

Subscribe
Upozornit na
guest
7 Komentářů
Nejstarší
Nejnovější Most Voted
Inline Feedbacks
View all comments
Čelo

> Můžete si stáhnout <a>zdrojové kódy
zatím nemůžeme ;)

vlabra

Tak jsem se na to koukl a vážně nevím. Asi už stárnu, ale ta syntaxe mi připadá taková divná. Samotná podstata jazyka i runtime mi připadají dobré, ale ta syntaxe mi příjde fakt otřesná. Jako by to nemohli přiblížit více Javě/C#. Takhle mám pocit jako by se pokoušeli znovu vynalézt kolo, a zase trochu jinak.

blizzboz

Čo sa týka Objective C tak odporúčam tento seriál:

http://bit.ly/cToczh

http://bit.ly/a3CGUe

http://bit.ly/crcrjb

Mohol by ten autor niekedy napísať niečo aj pre zdroják.

Jiří Knesl

Syntax je stará skoro 40 let. Používání @ a [] pro zprávy si tvůrci Objective-J mohli odpustit (je v Objective-C proto, aby byl jazyk kompatibilní s C a uvnitř se skoro všechno převádí na obyčejné C-čkovské zavolání funkce). Co se všeho ostatního týká, je syntax o světelný rok dál než syntax C# nebo Javy a kopírovat je by byl krok zpět. Čímž nechci vyvolat flamewar, kdo v Obj-C nebo Smalltalku píše, ví své, ostatní se přesvědčit stejně nedají, takže diskuze bývá bezpředmětná.

OldFrog

Doporučuju toto přátelské klání mezi Javou a Objective-C resp. panem Čadou a panem Viriusem:

http://www.ocs.cz/text/Java/

Enum a statická analýza kódu

Mám jednu univerzální radu pro začínající programátorty. V učení sice neexistují rychlé zkratky, ovšem tuhle radu můžete snadno začít používat a zrychlit tak tempo učení. Tou tajemnou ingrediencí je statická analýza kódu. Ukážeme si to na příkladu enum.