Základy Objective-J: syntaxe a framework Foundation

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.

Seriál: Vývoj aplikací v Cappuccinu (4 díly)

  1. Cappuccino – webové aplikace snadno a rychle 4.10.2010
  2. Základy Objective-J: syntaxe a framework Foundation 18.10.2010
  3. Cappuccino: uživatelské rozhraní aplikace a AppKit 11.11.2010
  4. Cappuccino: zobrazujeme tabulku s daty 1.12.2010

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).

Zabývá se návrhem a vývojem webových aplikací. Své nápady s důrazem na jednoduchost a použitelnost realizuje spolu se členy týmu abdoc.

Komentáře: 7

Přehled komentářů

Čelo oprava
Lukáš Hurych Re: oprava
vlabra Syntaxe
Lukáš Hurych Re: Syntaxe
blizzboz Re: Syntaxe
Jiří Knesl Re: Syntaxe
OldFrog Re: Syntaxe
Zdroj: https://www.zdrojak.cz/?p=3346