Jak se naučit jazyk
ACTIONSCRIPT® 3.0
Právní upozornění
Právní upozornění Právní upozornění viz http://help.adobe.com/cs_CZ/legalnotices/index.html.
Poslední aktualizace 12.5.2011
iii
Obsah Kapitola 1: Úvodní informace k jazyku ActionScript 3.0 O ActionScriptu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 Výhody jazyka ActionScript 3.0
......................................................................................... 1
Co je nového v jazyce ActionScript 3.0
................................................................................. 2
Kapitola 2: Začínáme s jazykem ActionScript Základy programování . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 Práce s objekty
........................................................................................................ 7
Společné prvky programu
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Příklad: Animace portfolia (Flash Professional) Vytváření aplikací v jazyce ActionScript Vytváření vlastních tříd
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Příklad: Vytváření základních aplikací
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Kapitola 3: Jazyk ActionScript a jeho syntaxe Přehled jazyka . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 Objekty a třídy
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
Balíčky a jmenné prostory Proměnné
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
Typy dat
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
Syntaxe
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
Operátory
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
Podmíněné příkazy Opakování Funkce
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
Kapitola 4: Objektově orientované programování v jazyce ActionScript Úvod k objektově orientovanému programování . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 Třídy
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
Rozhraní
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
Zdědění
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
Pokročilá témata
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
Příklad: GeometricShapes
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
Poslední aktualizace 12.5.2011
1
Kapitola 1: Úvodní informace k jazyku ActionScript 3.0 O ActionScriptu ActionScript je programovací jazyk pro prostředí přehrávače Adobe® Flash® Player a programu Adobe® AIR™ v době běhu. Umožňuje interakce, zpracovávání dat a další možnosti v obsahu a v aplikacích Flash, Flex a AIR. Jazyk ActionScript se provádí v aplikaci ActionScript Virtual Machine (AVM), která je součástí přehrávače Flash Player a programu AIR. Kód jazyka ActionScript se obvykle převádí pomocí kompilátoru do formátu bytového kódu. (Bytový kód je druh programovacího jazyka, který píší a rozpoznávají počítače.) Mezi kompilátory patří i kompilátor vestavěný v aplikaci Adobe® Flash® Professional a kompilátor vestavěný v aplikaci Adobe® Flash® Builder™, který je k dispozici v sadě SDK aplikace Adobe® Flex™. Bytový kód se vkládá do souborů SWF, jež provádí aplikace Flash Player a AIR. Jazyk ActionScript 3.0 nabízí stabilní programovací model, který dobře znají vývojáři se základní znalostí objektově orientovaného programování. Některé z klíčových funkcí jazyka ActionScript 3.0, které vylepšují předchozí verze jazyka ActionScript, zahrnují následující:
• Nový nástroj ActionScript Virtual Machine nazvaný AVM2, který používá novou sadu pokynů bytového kódu a nabízí o mnoho lepší výkon
• Modernější základ pro kód kompilátoru, který provede hlubší optimalizaci než předcházející verze kompilátoru • Rozšířené a vylepšené programovací rozhraní aplikace (API) s nízkoúrovňovým ovládáním objektů a správným na objekt orientovaným modelem
• Rozhraní API XML založené na ECMAScript pro specifikaci XML (E4X) (ECMA-357 vydání 2). E4X je rozšíření jazyka pro ECMAScript, které přidává XML jako nativní datový typ jazyka.
• Model události založený na specifikaci událostí na úrovni 3 modelu objektu dokumentu (DOM)
Výhody jazyka ActionScript 3.0 Jazyk ActionScript 3.0 předčí skriptovací schopnosti předcházejících verzí jazyka ActionScript. Jeho účelem je umožnit vytváření vysoce komplexních aplikací s velkými sadami dat a na objekt orientovanými, opětovně použitelnými základnami kódů. Jazyk ActionScript 3.0 není nezbytný pro obsah, který lze spustit v přehrávači Adobe Flash Player. Umožňuje však zlepšení výkonu, která jsou dostupná jen při použití aplikace AVM2 (virtuální počítač ActionScript 3.0). Kód v jazyce ActionScript 3.0 umí provádět operace až desetkrát rychleji než kód v dřívějších verzích jazyka ActionScript. Předchozí verze aplikace ActionScript Virtual Machine, AVM1, pracuje s kódem v jazyce ActionScript 1.0 a ActionScript 2.0. Přehrávače Flash Player 9 a 10 podporují aplikaci AVM1 kvůli zajištění zpětné kompatibility.
Poslední aktualizace 12.5.2011
2
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Úvodní informace k jazyku ActionScript 3.0
Co je nového v jazyce ActionScript 3.0 Jazyk ActionScript 3.0 obsahuje mnoho tříd a funkcí, které jsou podobné jako ve verzích ActionScript 1.0 a 2.0. Nicméně jazyk ActionScript 3.0 se od předchozích verzí jazyka ActionScript liší architektonicky a koncepčně. Vylepšení v jazyce ActionScript 3.0 zahrnují nové funkce základního jazyka a vylepšené rozhraní API přehrávače, které poskytuje lepší kontrolu objektů na nižších úrovních.
Základní jazykové prvky Základní jazyk definuje základní stavební bloky programovacího jazyka, například příkazy, výrazy, podmínky, opakování a typy. Jazyk ActionScript 3.0 obsahuje mnoho funkcí, jež urychlují proces vývoje. Výjimky v době běhu Jazyk ActionScript 3.0 hlásí více stavů chyb než předcházející verze jazyka ActionScript. Výjimky v době běhu jsou použity pro běžné stavy chyb, vylepšují zkušenosti s laděním a umožňují vám vyvinout aplikace, které účinně zpracovávají chyby. Chyby v době běhu mohou poskytnout sledování zásobníku, které je anotováno se zdrojovým souborem a informací a počtu řádků. Tím vám umožňují rychlé a přesné určení chyb. Typy v době běhu V jazyce ActionScript 3.0 jsou za běhu zachovány informace o typech. Tyto informace slouží k provádění kontroly typů za běhu, čímž se zvyšuje bezpečnost typů systému. Informace o typech se také používají ke znázornění proměnných v nativních reprezentacích počítače, což vylepšuje výkon a snižuje využití paměti. Pro srovnání – anotace typů v jazyce ActionScript 2.0 jsou především pomůckou pro vývojáře a všechny hodnoty se dynamicky typují za běhu. Uzavřené třídy Jazyk ActionScript 3.0 zahrnuje koncepci uzavřených tříd. Uzavřená třída má pouze fixní sadu vlastností a metod, které jsou definovány v době kompilace; další vlastnosti a metody přidat nelze. Vyloučení možnosti změnit třídu za běhu umožňuje přísnější kontrolu v době kompilace, takže programy jsou pak stabilnější. Vylepšuje také využití paměti tím, že nevyžaduje pro každou instanci objektu interní tabulku křížku. Dynamické třídy jsou také přístupné pomocí klíčového slova dynamic. Všechny třídy v definici jazyka ActionScript 3.0 jsou implicitně uzavřeny, ale lze je deklarovat tak, aby byly dynamické, a to s klíčovým slovem dynamic. Uzavření metody: Jazyk ActionScript 3.0 umožňuje uzavření metody pro automatické zapamatování si původní instance objektu. Tato funkce je užitečná pro zpracovávání událostí. V jazyce ActionScript 2.0 si uzavření metody nepamatují, z jaké instance objektu byla vyjmuta, což vede k nečekanému chování při volání uzavření metody. ECMAScript pro XML (E4X) Jazyk ActionScript 3.0 implementuje ECMAScript pro XML (E4X), nedávno standardizovaný jako ECMA-357. E4X nabízí přirozenou plynulou sadu jazykových konstruktů pro manipulaci s XML. Oproti tradiční analýze XML rozhraní API má XML s E4X funkce stejné jako nativní datový typ jazyka. E4X urychluje vývoj aplikací, které využívají jazyk XML, a to značným snížením potřebného množství kódu. Specifikaci ECMA E4X naleznete na stránce www.ecma-international.org. Regulární výrazy Jazyk ActionScript 3.0 zahrnuje nativní podporu pro regulární výrazy, takže můžete rychle vyhledávat řetězce a manipulovat s nimi. Jazyk ActionScript 3.0 implementuje podporu pro regulární výrazy dle jejich definice ve specifikaci jazyka ECMAScript (ECMA-262), 3. vydání.
Poslední aktualizace 12.5.2011
3
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Úvodní informace k jazyku ActionScript 3.0
Jmenné prostory Jmenné prostory se podobají tradičním specifikátorům přístupu používaným pro ovládání viditelnosti deklarací (public, private, protected). Pracují jako vlastní specifikátory přístupu, které můžete pojmenovat dle svého výběru. Pro zabránění kolizím jsou jmenné prostory vybaveny identifikátorem Universal Resource Identifier (URI) a jsou také používány pro reprezentaci jmenných prostorů XML při práci s E4X. Nové primitivní typy Jazyk ActionScript 3.0 zahrnuje tři číselné typy: Number, int, uint. Typ Number (číslo) představuje číslo s plovoucí čárkou s dvojitou přesností. Typ int je 32-bitové celé číslo se znaménkem, které umožňuje kódu jazyka ActionScript využít výhody rychlých matematických schopností celého čísla CPU. Typ int je užitečný pro čítače opakování a proměnné tam, kde jsou použita celá čísla. Typ uint je typ 32-bytového celého čísla bez znaménka, který je užitečný pro barevné hodnoty RGB, počty bytů, atd. Oproti tomu jazyk ActionScript 2.0 má jen jeden číselný typ, a to Number.
Funkce rozhraní API Rozhraní přehrávače API v jazyku ActionScript 3.0 obsahují mnoho tříd, které vám umožňují ovládat objekty na nízké úrovni. Architektura jazyka je navržena tak, aby byla intuitivnější než předchozí verze. Přestože třídy nelze vzhledem k jejich množství popisovat podrobně, za zmínku stojí několik podstatných rozdílů. Model události DOM3 Model událostí DOM3 (objektový model dokumentu úrovně 3) poskytuje standardní způsob generování a zpracování zpráv o událostech. Tento model událostí je navržen tak, aby objekty v rámci aplikací mohly vzájemně reagovat a komunikovat, zachovat si svůj stav a reagovat na změnu. Model událostí v jazyce ActionScript 3.0 byl vytvořen podle specifikace událostí Modelu objektu dokumentu (DOM) úrovně 3 sdružení W3C (World Wide Web Consortium). Tento model poskytuje přehlednější a efektivnější mechanismus než systémy událostí v předchozích verzích jazyka ActionScript. Události a události chyb jsou umístěny v balíku flash.events. Komponenty aplikace Flash Professional a rámec Flex používají stejný model událostí, takže systém událostí je v celé platformě Flash jednotný. Rozhraní API seznamu zobrazení Rozhraní API pro přístup k seznamu zobrazení – stromová struktura, která obsahuje jakékoliv vizuální elementy v aplikaci – se skládá z tříd pro práci se základními vizuálními tvary. Třída Sprite je odlehčený stavební prvek, jenž má být základní třídou pro vizuální elementy, např. komponenty uživatelského rozhraní. Třída Shape představuje prosté vektorové tvary. Tyto třídy lze přirozeně konkretizovat pomocí operátoru new a lze je kdykoliv dynamicky znovu přiřadit jako nadřazené. Hloubková správa probíhá automaticky. Jsou k dispozici metody pro určení a ovládání pořadí překrývání objektů. Zpracovávání dynamických dat a obsahu Jazyk ActionScript 3.0 obsahuje mechanismy pro načítání a zpracovávání datových zdrojů a dat ve vaší aplikaci, které jsou intuitivní a ve všech rozhraních API stejné. Třída Loader poskytuje jediný mechanismus pro načítání souborů SWF a datových zdrojů obrazů a zajišťuje získání přístupu k podrobným informacím o načteném obsahu. Třída URLLoaderposkytuje samostatný mechanismus pro načítání textu a binárních dat v aplikacích zaměřených na data. Třída Socket poskytuje způsob načtení a zapsání binárních dat na servery soketů, a to v jakémkoliv formátu.
Poslední aktualizace 12.5.2011
4
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Úvodní informace k jazyku ActionScript 3.0
Přístup k datům na nízké úrovni Různá rozhraní API poskytují k datům přístup nižší úrovně. Pro načítaná data poskytuje třída URLStream během načítání přístup k datům jako k prvotním binárním datům. Třída ByteArray umožňuje optimalizovat čtení, zápis a práci s binárními daty. Zvukové rozhraní API poskytuje podrobné ovládání zvuku pomocí tříd SoundChannel a SoundMixer. Zabezpečovací rozhraní API poskytují informace o právech zabezpečení souboru SWF nebo načteného obsahu a umožňují tak lepší zpracování chyb zabezpečení. Práce s textem Jazyk ActionScript 3.0 obsahuje balík flash.text pro všechna rozhraní API související s textem. Třída TextLineMetrics poskytuje podrobnou metriku pro řádek textu v rámci textového pole; nahrazuje metodu TextFormat.getTextExtent() v jazyce ActionScript 2.0. Třída TextField obsahuje metody nízké úrovně, jež poskytují specifické informace o řádku textu nebo jednotlivém znaku v textovém poli. Například metoda getCharBoundaries() vrátí obdélník představující ohraničovací rámeček znaku. Metoda getCharIndexAtPoint() vrátí index znaku v určeném bodě. Metoda getFirstCharInParagraph() vrátí index prvního znaku v odstavci. Mezi metody na úrovni řádku patří getLineLength(), která vrátí počet znaků na určitém řádku textu, a getLineText(), která vrátí text určeného řádku. Třída Font poskytuje způsob ovládání vnořených písem v souborech SWF. Pro zajištění kontroly nad textem na ještě nižší úrovni tvoří třídy v balíku flash.text.engine společně modul Flash Text Engine. Tato sada tříd poskytuje kontrolu nad textem na nízké úrovni a slouží k vytváření rámců a komponent textu.
Poslední aktualizace 12.5.2011
5
Kapitola 2: Začínáme s jazykem ActionScript Základy programování Protože ActionScript je programovací jazyk, může být při jeho studiu užitečné nejprve porozumět několika obecným konceptům počítačového programování.
Co dělají počítačové programy Nejprve je vhodné koncepčně porozumět tomu, co počítačový program je a co má za úkol. Existují dva hlavní aspekty počítačového programu:
• Program je sledem instrukcí nebo kroků, které má počítač provádět. • Každý krok znamená zpracování části informace nebo dat. V obecném smyslu je počítačový pouze seznamem posloupností instrukcí, které předáváme počítači, aby je jednu za druhou provedl. Každá jednotlivá instrukce se nazývá příkaz. V jazyce ActionScript je každý příkaz zakončen středníkem. V podstatě všechny instrukce uvedené v programu zpracovávají určité množství dat, která jsou uložena v paměti počítače. Jednoduchým příkladem může být pokyn, aby počítač sečetl dvě čísla a uložil výsledek do paměti. Jako složitější příklad si představte, že na obrazovce je vykreslen obdélník a vaším úkolem je napsat program, který jej přesune na jiné místo na obrazovce. Počítač si pamatuje určité informace o obdélníku: souřadnice X, Y umístění, jeho šířku a výšku, barvu atd. Každá taková část informací je uložena na určitém místě v paměti počítače. Program zajišťující posun obdélníku na jiné místo bude zahrnovat kroky, jako např. „změnit souřadnici X na 200; změnit souřadnici Y na 150“. Jinými slovy určí nové hodnoty souřadnic X a Y. V pozadí přitom počítač zpracuje data a převede tato čísla na obraz, který se zobrazí na obrazovce. Jako základ však stačí vědět, že proces „posunutí obdélníku po obrazovce“ vyžaduje přeměnu kusů dat v paměti počítače.
Proměnné a konstanty Programování z převážné části sestává z přeměny jednotlivých informací v paměti počítače. Proto je důležité mít možnost vyjádřit každou informaci v programu. Proměnná je název vyjadřující hodnotu v paměti počítače. Při zapisování příkazů pro zpracování hodnot zapisujete místo hodnoty název proměnné. Kdykoliv počítač vidí v programu název proměnné, prohledá paměť a použije hodnotu, kterou zde nalezne. Pokud například máte dvě proměnné pojmenované hodnota1 a hodnota2 a každá obsahuje číslo, můžete pro sečtení těchto čísel zadat příkaz: value1 + value2
Při provádění těchto kroků počítač vyhledá hodnoty každé proměnné a poté je sečte. V jazyce ActionScript 3.0 je proměnná tvořena třemi různými součástmi:
• Název proměnné • Typ dat, které lze do proměnné uložit • Skutečná hodnota uložená v paměti počítače
Poslední aktualizace 12.5.2011
6
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Začínáme s jazykem ActionScript
Viděli jste, jak počítač používá název jako vyhrazené místo pro hodnotu. Typ dat je také důležitý. Při vytváření proměnné v jazyce ActionScript definujete konkrétní typ dat, která v ní mají být uložena. Od tohoto okamžiku bude v pokynech programu možné do této proměnné uložit pouze tento typ dat. Hodnotu lze zpracovávat za použití určitých vlastností spojených s jejím typem dat. V jazyce ActionScript vytváříte proměnnou (tento proces se nazývá deklarování proměnné) pomocí příkazu var: var value1:Number;
V tomto příkladu dostane počítač pokyn, aby vytvořil proměnnou s názvem value1, v níž mohou být uložena pouze data typu Number (číslo). („Number“ je určitý datový typ definovaný v jazyce ActionScript.) Hodnotu můžete také uložit přímo do proměnné: var value2:Number = 17;
Adobe Flash Professional V aplikaci Flash Professional existuje jiný způsob, jak deklarovat proměnnou. Když umístíte symbol filmového klipu, symbol tlačítka nebo textové pole na plochu, můžete jej pojmenovat názvem instance v Inspektoru vlastností. Aplikace Flash Professional vytvoří v pozadí proměnnou, jejíž název je shodný s názvem instance. Tento název lze použít v kódu jazyka ActionScript k vyjádření dané položky Stage. Předpokládejme například, že se na ploše nachází symbol filmového klipu, kterému přiřadíte název instance rocketShip. Pokaždé, když v kódu jazyka ActionScript použijete proměnnou rocketShip, budete v podstatě pracovat s tímto filmovým klipem.
Konstanta je podobná proměnné. Jedná se o název, který představuje hodnotu v paměti počítače s určeným typem dat. Rozdíl je v tom, že konstanta může mít přiřazenou hodnotu pouze v průběhu aplikace jazyka ActionScript. Jakmile je hodnota konstanty přiřazena, je stejná v celé aplikaci. Syntaxe pro deklarování konstanty je téměř stejná jako při deklarování proměnné. Jediný rozdíl je v tom, že se místo klíčového slova var použije klíčové slovo const. const SALES_TAX_RATE:Number = 0.07;
Konstanta je užitečná k definování hodnoty použité na několika místech v projektu, která se za normálních okolností nemění. Použitím konstanty namísto literálové hodnoty bude váš kód čitelnější. Zvažte například dvě verze stejného kódu. V jedné se cena násobí konstantou SALES_TAX_RATE. Ve druhé se cena násobí číslem 0,07. Verze používající konstantu SALES_TAX_RATE je snáze pochopitelná. Dále předpokládejme, že se hodnota definovaná konstantou mění. Jestliže v celém projektu použijete k vyjádření této hodnoty konstantu, stačí změnit hodnotu na jediném místě (v deklaraci konstanty). Naproti tomu při použití pevně zakódovaných hodnot literálů bude nutné hodnotu změnit na různých místech.
Typy dat V jazyce ActionScript existuje mnoho datových typů, které můžete použít jako datový typ vytvářené proměnné. Některé z těchto datových typů lze považovat za „jednoduché“ nebo „základní“ datové typy:
• String (řetězec): textová hodnota, například název nebo text kapitoly knihy • Numeric (číselný typ): jazyk ActionScript 3.0 zahrnuje tři specifické datové typy pro číselná data: • Number (číslo): kterákoliv číselná hodnota, zahrnující hodnoty se zlomkem nebo bez něj • int: celočíselná hodnota (celé číslo bez zlomku) • uint: celočíselná hodnota bez znaménka, což znamená, že celé číslo nemůže být záporné • Boolean (booleovská hodnota): logická hodnota PRAVDA nebo NEPRAVDA, například jako přepínač, který může být zapnutý nebo vypnutá, nebo zad se dvě hodnoty rovnají či nikoliv
Poslední aktualizace 12.5.2011
7
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Začínáme s jazykem ActionScript
Jednoduché datové typy představují jednotlivý kus informací: například jedno číslo nebo jednu posloupnost textu. Nicméně většina datových typů definovaných v jazyce ActionScript jsou komplexní datové typy. Představují sadu hodnot v jediném kontejneru. Například proměnná s datovým typem Date představuje jednu hodnotu (časový okamžik). Tato hodnota data je však zastoupena jako několik hodnot: den, měsíc, rok, hodina, minuta, sekunda atd., přičemž všechny jsou jednotlivými čísly. O datu obvykle uvažujeme jako o jediném čísle a při vytvoření proměnné Date lze datum zpracovávat jako jednu hodnotu. Počítač ji však interně zpracovává jako skupinu několika hodnot, které při složení dohromady dávají jediné datum. Většina z vestavěných datových typů a také datových typů definovaných programátory jsou komplexní datové typy. Mezi komplexní datové typy patří i následující:
• MovieClip: symbol filmového klipu • TextField: dynamické nebo vstupní textové pole • SimpleButton: symbol tlačítka • Date: informace o jednotlivém okamžiku v čase (datum a čas) Dvě slova, která jsou často používána jako synonymum pro datový typ, jsou třída a objekt. Třída je jednoduše definicí datového typu. Slouží jako šablona pro všechny objekty daného datového typu, jako by říkala „všechny proměnné datového typu Example mají tyto vlastnosti: A, B a C“. Naproti tomu objekt je jen konkrétní instancí třídy. Například proměnnou s datovým typem MovieClip lze popsat jako objekt MovieClip. Níže jsou uvedeny různé způsoby, jak vyjádřit stejnou věc:
• Datový typ proměnné myVariable je Number. • Proměnná myVariable je instancí Number. • Proměnná myVariable je objektem Number. • Proměnná myVariable je instancí třídy Number.
Práce s objekty Jazyk ActionScript znám jako objektově orientovaný programovací jazyk. Objektově orientovaného programování je jednoduše přístup k programování. Ve skutečnosti to není nic jiného než způsob uspořádání kódu v programu pomocí objektů. Dříve byl termín „počítačový program“ definován jako série kroků nebo pokynů prováděných počítačem. Koncepčně je pak možné si představit počítačový program jako jeden dlouhý seznam pokynů. Nicméně v objektově orientovaném programování jsou pokyny programu rozděleny mezi různé objekty. Kód je seskupen do shluků funkcí, takže související typy funkcí nebo související informace jsou seskupeny v jednom kontejneru. Adobe Flash Professional Pokud jste v aplikaci Flash Professional pracovali se symboly, již jste zvyklí na práci s objekty. Představte si, že jste definovali symbol filmového klipu, např. vykreslení obdélníku, a umístili jste jeho kopii na plochu. Tento symbol filmového klipu je (doslova) objektem v jazyce ActionScript, instancí třídy MovieClip.
Poslední aktualizace 12.5.2011
8
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Začínáme s jazykem ActionScript
Existují různé charakteristiky filmového klipu, které můžete změnit. Po jeho vybrání lze v Inspektoru vlastností změnit jeho hodnoty, např. souřadnici X nebo šířku. Rovněž lze provádět různé úpravy barvy, např. změnit jeho hodnotu alfa (průhlednost) nebo aplikovat filtr vrženého stínu. Jiné nástroje aplikace Flash Professional umožňují provádění dalších změn, například použití nástroje Volná transformace k otočení obdélníku. Všechny tyto způsoby, jimiž lze v aplikaci Flash Professional upravovat symbol filmového klipu, jsou rovněž dostupné v jazyce ActionScript. V jazyce ActionScript lze filmový klip upravit změnou dat, která jsou sloučena v jediném balíku zvaném objekt MovieClip.
V objektově orientovaném programování v jazyce ActionScript existují tři typy charakteristiky, které může obsahovat kterákoliv třída.
• Vlastnosti • Metody • Události Tyto prvky slouží pro správu kusů dat použitých programem a pro rozhodování o tom, které činnosti se budou provádět a v jakém pořadí.
Vlastnosti Vlastnost představuje jeden z kusů dat, které jsou seskupené dohromady do objektu. Vzorový objekt song může mít vlastnosti pojmenované artist a title; třída MovieClip má vlastnosti rotation, x, width a alpha. S vlastnostmi se pracuje jako s jednotlivými proměnnými. Vlastnosti si lze v podstatě představit jako „podřízené“ proměnné obsažené v objektu. Zde jsou některé příklady kódu jazyka ActionScript využívajícího vlastnosti. Tento řádek kódu pohybuje klipem MovieClip pojmenovaným square do souřadnice X o 100 obrazových bodů: square.x = 100;
Tento kód používá vlastnost rotation k otočení MovieClip square tak, aby to odpovídalo otočení MovieClip triangle: square.rotation = triangle.rotation;
Tento kód upraví horizontální stupnici třídy MovieClip square tak, aby byla 1,5krát větší než předtím: square.scaleX = 1.5;
Povšimněte si společné struktury: používáte proměnnou (square, triangle) jako název objektu, následuje tečka (.) a pak název vlastnosti (x, rotation, scaleX). Tečka, které se říká operátor dot, se používá k označení přístupu k jednomu z podřízených prvků objektu. Celá struktura společně, „název proměnné-tečka-název vlastnosti“ se používá jako jedna proměnná, jako název jedné hodnoty v paměti počítače.
Metody Metoda je akce, kterou může objekt provést. Předpokládejme například, že v aplikaci Flash Professional byl vytvořen symbol filmového klipu, na jehož časové ose je několik klíčových snímků a animací. Filmový klip se může přehrát nebo zastavit, nebo může dát přehrávací hlavě pokyn, aby se přesunula na konkrétní snímek. Tento kód vydává instrukci klipu MovieClip pojmenovanému shortFilm, aby se začal přehrávat: shortFilm.play();
Tato řádka způsobí zastavení klipu MovieClip pojmenovaného shortFilm (přehrávací hlava se zastaví na místě, jako při pozastavení videa):
Poslední aktualizace 12.5.2011
9
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Začínáme s jazykem ActionScript
shortFilm.stop();
Tento kód vydává instrukci klipu MovieClip pojmenovanému shortFilm přesunout přehrávací hlavu na snímek Frame 1 a zastavit přehrávání (jako při převíjení videa): shortFilm.gotoAndStop(1);
Metody, podobně jako vlastnosti, jsou přístupné zapsáním názvu objektu (proměnné), pak tečky, pak názvu metody následované závorkami. Závorky jsou způsobem, jak naznačit, že voláte metodu. Jinými slovy dávají objektu pokyn, aby provedl danou činnost. Někdy jsou hodnoty (či proměnné) umístěny do závorek kvůli předání dalších informací, které jsou nezbytné k provedení činnosti. Tyto hodnoty jsou známy jako parametry metody. Například metoda gotoAndStop() potřebuje informace o tom, na který snímek má přejít, takže vyžaduje v závorkách jeden parametr. Jiné metody, jako play() a stop(), jsou zřejmé a nevyžadují další informace. Nicméně jsou i přesto psány se závorkami. Na rozdíl od vlastností (a proměnných) nejsou metody použity jako vyhrazená místa pro hodnotu. Některé metody však mohou provádět výpočty a vracet výsledky, které lze použít jako proměnnou. Například metoda toString() třídy Number převádí číselnou hodnotu na textové vyjádření. var numericData:Number = 9; var textData:String = numericData.toString();
Metodu toString() můžete například použít v případě, že chcete zobrazit hodnotu proměnné Number v textovém poli na obrazovce. Vlastnost text třídy TextField je definována jako řetězec, takže může obsahovat pouze textové hodnoty. (Vlastnost property textu představuje vlastní obsah textu zobrazeného na obrazovce.) Tento řádek kódu převede číselnou hodnotu v proměnné numericData na text. Pak tuto hodnotu zobrazí na obrazovce v objektu TextField s názvem calculatorDisplay: calculatorDisplay.text = numericData.toString();
Události Počítačový program je řada pokynů, které počítač vykonává krok za krokem. Některé jednoduché počítačové programy nejsou tvořeny ničím jiným než několika kroky, které počítač provede, a program se poté ukončí. Programy v jazyce ActionScript jsou však navrženy tak, aby se uchovaly v chodu, vyčkaly na vstup uživatele nebo jinou událost. Události jsou mechanismy jež stanoví, které instrukce počítač provede a kdy. V podstatě jsou události věci, které nastávají, kterých si je jazyk ActionScript vědom a může na ně reagovat. Řada událostí souvisí s činností uživatele, např. s kliknutím na tlačítko nebo se stisknutím klávesy na klávesnici. Existují také další typy událostí. Pokud například použijete jazyk ActionScript k načtení externího obrázku, existuje událost, která vás vyrozumí, když načítání obrázku skončí. Když je spuštěn program v jazyce ActionScript, koncepčně jen čeká, až se stanou určité věci. Jakmile k nim dojde, spustí se kód v jazyce ActionScript, který byl pro tyto události definován.
Základní zpracování událostí Technika specifikování jistých činností, které mají být provedeny v odezvě na určité události, je známá jako zpracování událostí. Když zapisujete kód v jazyce ActionScript k provedení zpracování události, existují tři důležité prvky, které musíte identifikovat:
• Zdroj události: který objekt je ten, jemuž se událost přihodí? Například na které tlačítko bylo kliknuto, nebo který objekt Loader načítá obrázek? Zdroj události se rovněž nazývá cíl události. Říká se mu tak proto, že se jedná o objekt, kde počítač zaměří událost (tj. kde k události vlastně dojde).
• Událost: Jaká akce bude provedena, tj. akce, na kterou chcete reagovat? Tuto konkrétní událost je důležité identifikovat, protože mnoho objektů spouští několik událostí.
• Odezva: jaké kroky mají být provedeny, když k události dojde?
Poslední aktualizace 12.5.2011
10
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Začínáme s jazykem ActionScript
Každý kód napsaný v jazyce ActionScript pro zpracování událostí vyžaduje tyto tři elementy. Kód sleduje tuto základní strukturu (elementy psané tučně jsou vyhrazená místa, která by se vyplnila pro určitý případ): function eventResponse(eventObject:EventType):void { // Actions performed in response to the event go here. } eventSource.addEventListener(EventType.EVENT_NAME, eventResponse);
Tento kód provádí dva kroky. Nejprve definuje funkci, která je způsobem specifikace činností, které budou provedeny v odezvě na událost. Potom zavolá metodu addEventListener() zdrojového objektu. Volání metody addEventListener() v podstatě „upíše“ tuto funkci určené události. Když k události dojde, provedou se činnosti funkce. Zvažte každou z těchto částí podrobněji. Funkce poskytuje způsob, kterým lze seskupit činnosti pod jedním názvem, který slouží jako název zástupce k provedení činností. Funkce je stejná jako metoda s tím rozdílem, že nemusí být nutně spojená s určitou třídou. (Termín „metoda“ lze definovat jako funkci, která je spojená s určitou třídou.) Při vytváření funkce pro zpracování událostí, musíte vybrat název této funkce (v tomto případě se nazývá eventResponse). Kromě toho je třeba určit jeden parametr (v tomto případě má název eventObject). Specifikování parametru funkce je jako deklarování proměnné, takže musíte také uvést datový typ parametru. (V tomto příkladu je datový typ parametru EventType.) Každý typ události, které chcete naslouchat, má připojenou třídu jazyka ActionScript. Specifikovaný datový typ pro parametr funkce je vždy přidruženou třídou specifické události, na kterou chcete reagovat. Například událost click (spustí se, když uživatel klikne na položku myší) je spojena s třídou MouseEvent. Chcete-li zapsat funkci posluchače pro událost click, definujete funkci posluchače pomocí parametru typu dat MouseEvent. Nakonec mezi levou a pravou složenou závorku ({ ... }) napište pokyny, které má počítač provést, když k události dojde. Funkce pro zpracování události je napsaná. Potom přikážete zdrojovému objektu události (objekt, kterému se událost stane, např. tlačítko), aby zavolal danou funkci, když k události dojde. Funkci lze zaregistrovat se zdrojovým objektem události voláním metody addEventListener() tohoto objektu (všechny objekty, jež mají události, mají také metodu addEventListener()). Metoda addEventListener()má dva parametry:
• První, název specifické události, na kterou chcete reagovat. Každá událost je připojená k určité třídě. Každá třída události má pro každou ze svých událostí definovánu zvláštní hodnotu, která slouží jako jedinečný název. Tato hodnota se použije pro první parametr.
• Druhý, název funkce odezvy na událost. Povšimněte si, že název funkce je zapsán bez závorek, když je předáván jako parametr.
Proces zpracování událostí Následující podrobný popis se věnuje procesu, který nastává, když vytvoříte posluchače události. V tomto případě je příkladem vytvoření funkce posluchače, která je zavolaná po klepnutí na objekt nazvaný myButton. Skutečný programátorem zapsaný kód je následující: function eventResponse(event:MouseEvent):void { // Actions performed in response to the event go here. } myButton.addEventListener(MouseEvent.CLICK, eventResponse);
Poslední aktualizace 12.5.2011
11
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Začínáme s jazykem ActionScript
Zde je uvedeno, jak by kód pracoval při spuštění: 1 Když se načte soubor SWF, počítač zaregistruje, že existuje funkce s názvem eventResponse().
2 Počítač pak spustí kód (konkrétně řádky kódu, které nejsou funkcí). V tomto případě se jedná pouze o jednu řádku
kódu: volání metody addEventListener() pro objekt zdroje události (s názvem myButton) a předání funkci eventResponse jako parametr.
Objekt myButton interně uchovává seznam funkcí, jež poslouchají každou z jeho událostí. Po zavolání metody addEventListener() objekt myButton uloží funkci eventResponse() do seznamu posluchačů událostí.
Poslední aktualizace 12.5.2011
12
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Začínáme s jazykem ActionScript
3 V některém bodě uživatel klepne na objekt myButton, spustí událost click (identifikována v kódu jako MouseEvent.CLICK).
V tento okamžik nastane následující: a Vytvoří se objekt, který je instancí třídy spojené s danou událostí (v tomto příkladu je to událost MouseEvent).
U řady událostí je tento objekt instancí třídy Event. V případě událostí myši je to instance třídy MouseEvent. U dalších událostí se jedná o instanci třídy, která je spojena s danou událostí. Tento vytvořený objekt se nazývá objekt události a obsahuje specifické informace o události, která proběhla: o jaký typ události se jedná, kde k ní došlo a ostatní informace specifické pro danou událost, pokud jsou k dispozici.
b Počítač poté vyhledá posluchače událostí uložené objektem myButton. Postupně projde tyto funkce, zavolá
každou z nich a předá objekt události funkci jako parametr. Jelikož je funkce eventResponse() jednou z posluchačů objektu myButton, jako součást tohoto procesu počítač zavolá funkci eventResponse().
Poslední aktualizace 12.5.2011
13
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Začínáme s jazykem ActionScript
c Když je zavolána funkce eventResponse(), kód v této funkci se spustí, takže jsou vykonány specifikované
činnosti.
Příklady zpracování událostí Zde je uvedeno několik konkrétnějších příkladů kódu pro zpracování událostí. Pomocí těchto příkladů se seznámíte s několika běžnými elementy událostí a s možnými obměnami, které jsou při psaní kódu pro zpracování událostí k dispozici:
• Klepnutím na tlačítko spustíte přehrávání stávajícího filmového klipu. V následujícím příkladu je playButton název instance tlačítka a this je speciální název, mající význam „stávající objekt“: this.stop(); function playMovie(event:MouseEvent):void { this.play(); } playButton.addEventListener(MouseEvent.CLICK, playMovie);
• Detekce zadávání textu do pole. V tomto příkladu je entryText vstupní textové pole a outputText je dynamické textové pole: function updateOutput(event:TextEvent):void { var pressedKey:String = event.text; outputText.text = "You typed: " + pressedKey; } entryText.addEventListener(TextEvent.TEXT_INPUT, updateOutput);
• Klepnutí na tlačítko a přesun na adresu URL. V tomto příkladu je linkButton názvem instance tlačítka: function gotoAdobeSite(event:MouseEvent):void { var adobeURL:URLRequest = new URLRequest("http://www.adobe.com/"); navigateToURL(adobeURL); } linkButton.addEventListener(MouseEvent.CLICK, gotoAdobeSite);
Poslední aktualizace 12.5.2011
14
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Začínáme s jazykem ActionScript
Vytváření instancí objektu Aby bylo možné objekt v jazyce ActionScript použít, musí tento objekt nejprve existovat. Jednou z částí procesu vytváření objektu je deklarování proměnné. Toto deklarování však pouze vytvoří prázdné místo v paměti počítače. Proměnné vždy přiřaďte skutečnou hodnotu (vytvořte objekt a uložte jej do proměnné), než ji zkusíte použít nebo zpracovat. Procesu tvorby objektu se říká vytvoření instance objektu. Jinými slovy vytvoříte instanci určité třídy. Jednoduchý způsob vytvoření instance objektu vůbec nevyžaduje jazyk ActionScript. V aplikaci Flash Professional umístěte na plochu symbol filmového klipu, symbol tlačítka nebo textové pole a přiřaďte mu název instance. Aplikace Flash Professional automaticky deklaruje proměnnou s tímto názvem instance, vytvoří instanci objektu a uloží tento objekt do proměnné. Podobně lze i v aplikaci Flex vytvořit komponentu v jazyce MXML buďto napsáním kódu tagu MXML, nebo umístěním komponenty do editoru aplikace Flash Builder v režimu Design. Když této komponentě přiřadíte ID, stane se z tohoto ID název proměnné v jazyce ActionScript obsahující instanci této komponenty. Někdy však nemusíte chtít vytvářet objekt vizuálně a u nevizuálních objektů to není možné. Existuje řada dalších způsobů, jak lze vytvořit instance objektů pouze pomocí jazyka ActionScript. S několika datovými typy jazyka ActionScript můžete vytvořit instanci pomocí literálového výrazu, což je hodnota zapsaná přímo do kódu jazyka ActionScript. Zde jsou uvedeny některé příklady:
• Literálová číselná hodnota (zadejte číslo přímo): var someNumber:Number = 17.239; var someNegativeInteger:int = -53; var someUint:uint = 22;
• Literálová hodnota řetězce (text uložte do uvozovek): var firstName:String = "George"; var soliloquy:String = "To be or not to be, that is the question...";
• Literálové booleovská hodnota (použijte literálové hodnoty true nebo false): var niceWeather:Boolean = true; var playingOutside:Boolean = false;
• Literálová hodnota pole (seznam hodnot oddělených čárkami v vložte do hranatých závorek): var seasons:Array = ["spring", "summer", "autumn", "winter"];
• Literálová hodnota XML (zadejte XML přímo): var employee:XML = <employee> Harold Webster ;
Jazyk ActionScript také definuje literálové výrazy pro datové typy Array, RegExp, Object a Function. Nejběžnější způsob vytvoření instance pro libovolný datový typ je použití operátoru new s názvem třídy, jak je znázorněno zde: var raceCar:MovieClip = new MovieClip(); var birthday:Date = new Date(2006, 7, 9);
Vytvoření objektu pomocí operátoru new je často označováno jako „volání konstruktoru třídy“. Konstruktor je speciální metodou volanou jako část procesu vytváření instance třídy. Všimněte si, že při vytváření instance tímto způsobem se za název třídy vkládají závorky. Někdy se v závorkách definují hodnoty parametrů. Tyto dvě činnosti se rovněž provádějí při volání metody. I pro datové typy, které umožňují vytvářet instance pomocí literálového výrazu, lze rovněž použít operátor new k vytvoření instance objektu. Například tyto dva řádky kódu provádějí stejnou činnost:
Poslední aktualizace 12.5.2011
15
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Začínáme s jazykem ActionScript
var someNumber:Number = 6.33; var someNumber:Number = new Number(6.33);
Je důležité se dobře seznámit s vytvářením objektů způsobem newClassName(). Řada datových typů jazyka ActionScript nemá vizuální znázornění. Tudíž je nelze vytvořit umístěním položky na plochu aplikace Flash Professional ani v režimu Design editoru MXML aplikace Flash Builder. Instance těchto datových typů lze v jazyce ActionScript vytvářet pouze pomocí operátoru new. Adobe Flash Professional V aplikaci Flash Professional lze operátor new rovněž použít k vytvoření instance symbolu filmového klipu, který je definován v knihovně, ale není umístěn na ploše.
Další témata nápovědy Práce s poli Používání regulárních výrazů Vytváření objektů MovieClip pomocí kódu ActionScript
Společné prvky programu Při vytváření programu v jazyce ActionScript se používá také několik dalších stavebních bloků.
Operátory Operátory jsou speciální symboly (nebo příležitostně slova), která jsou používána k provádění výpočtů. Jsou většina používány pro matematické operace a rovněž pro porovnávání hodnot. Operátor obecně používá jednu nebo více hodnot a „vypracuje“ jeden výsledek. Například:
• Operátor sčítání (+) sečte dvě hodnoty a vytvoří jedno číslo: var sum:Number = 23 + 32;
• Operátor násobení (*) vynásobí jednu hodnotu druhou a vytvoří jedno číslo: var energy:Number = mass * speedOfLight * speedOfLight;
• Operátor rovnosti (==) porovná dvě hodnoty a poskytne výsledek ve formě jedné booleovské hodnoty (pravda nebo nepravda). if (dayOfWeek == "Wednesday") { takeOutTrash(); }
Jak je zde znázorněno, operátor rovnosti a další operátory „porovnání“ se nejčastěji používají s příkazem if, který určí, zda budou určité pokyny vykonány nebo nikoliv.
Poslední aktualizace 12.5.2011
16
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Začínáme s jazykem ActionScript
Poznámky Při psaní kódu v jazyce ActionScript si pro sebe můžete chtít nechat některé poznámky. Někdy například chcete vysvětlit, jak fungují některé řádky kódu, nebo proč byla zvolena určitá možnost. Komentáře kódu jsou nástrojem pro zapsání textu, který bude počítač v kódu ignorovat. Jazyk ActionScript zahrnuje dva typy komentářů:
• Jednořádkový komentář: jednořádkový komentář je označen vložením dvou lomítek kdekoliv do řádky. Počítač ignoruje vše, co následuje za lomítky až na konec daného řádku: // This is a comment; it's ignored by the computer. var age:Number = 10; // Set the age to 10 by default.
• Víceřádkový komentář: víceřádkový komentář zahrnuje značku počátku (/*), pak samotný obsah a nakonec značku konce (*/). Počítač ignoruje vše mezi počáteční a koncovou značkou bez ohledu na to, kolik řádků komentář zahrnuje: /* This is a long description explaining what a particular function is used for or explaining a section of code. In any case, the computer ignores these lines. */
Dále se komentáře běžně používají k dočasnému „vypnutí“ jednoho či několika řádků kódu. Komentáře lze například využít, jestliže zkoušíte jiný způsob provedení určité věci. Rovněž je můžete použít, když se snažíte zjistit, proč určitý kód v jazyce ActionScript nefunguje podle očekávání.
Řízení toku Mnohokrát potřebujete v programu opakovat jisté činnosti, provést pouze některé činnosti a jiné nikoliv, provést alternativní činnosti v závislosti na určitých podmínkách atd. Řízení toku je ovládáním provádění jednotlivých činností. Existuje několik typů prvků řízení tok, které jsou v jazyce ActionScript dostupné.
• Funkce: funkce jsou jako zástupci. Poskytují možnost seskupení řady činností pod jedním názvem a mohou být použity k provedení výpočtů. Funkce jsou nezbytné ke zpracování událostí, slouží ale také jako obecné nástroje k seskupení řady pokynů.
• Cykly: Struktury cyklů umožňují označit sadu pokynů, kterou počítač provádí po stanovený počet opakování nebo dokud se nezmění stanovená podmínka. Cykly se často používají pro zpracování několika souvisejících položek, pomocí proměnné, jejíž hodnota se změní pokaždé, když počítač dokončí jednotlivý cyklus.
• Podmíněné příkazy: podmíněné příkazy poskytují způsob pro vymezení určitých pokynů, které budou provedeny pouze za jistých podmínek. Rovněž se používají k vytvoření alternativních sad pokynů pro odlišné podmínky. Nejběžnějším typem podmíněného příkazu je příkaz if. Příkaz if kontroluje hodnotu nebo výraz v závorkách. Mají-li hodnotu true, budou řádky kódu ve složených závorkách provedeny. V opačném případě budou ignorovány. Například: if (age < 20) { // show special teenager-targeted content }
Společník příkazu if, příkaz else, umožňuje určit alternativní pokyny, které počítač provede, pokud podmínka nebude mít hodnotu true:
Poslední aktualizace 12.5.2011
17
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Začínáme s jazykem ActionScript
if (username == "admin") { // do some administrator-only things, like showing extra options } else { // do some non-administrator things }
Příklad: Animace portfolia (Flash Professional) Tento příklad je navržen tak, abyste měli příležitost vidět, jak lze sestavit kusy kódu ActionScript do kompletní aplikace. Část s portfoliem animací ukazuje, že je možné vzít existující lineární animaci a přidat několik drobných interaktivních prvků. Do online portfolia lze například začlenit animaci vytvořenou pro klienta. Interaktivní chování, které se přidá do animace, zahrnuje dvě tlačítka, na než může uživatel kliknout: jedno pro spuštění animace a druhé pro přechod na samostatnou adresu URL (například nabídka portfolia nebo úvodní stránka autora). Proces vytvoření tohoto kusu lze rozdělit do následujících hlavních částí: 1 Připravení souboru FLA pro přidání kódu v jazyce ActionScript a interaktivních prvků. 2 Vytvoření a přidání tlačítek. 3 Zapsání kódu v jazyce ActionScript. 4 Testování aplikace.
Příprava na přidání interaktivních prvků Před přidáním interaktivních prvků do animace je vhodné nastavit soubor FLA vytvořením několika míst pro přidání nového obsahu. Tato úloha zahrnuje vytvoření vlastního prostoru na ploše, kam lze umístit tlačítka. Rovněž zahrnuje vytvoření „prostoru“ v souboru FLA, aby různé položky zůstaly oddělené. Chcete-li nastavit soubor FLA pro přidání interaktivních prvků: 1 Vytvořte soubor FLA s jednoduchou animací, např. s jedním doplněním pohybu nebo doplněním tvaru. Jestliže již máte soubor FLA obsahující animaci, která se objevuje v projektu, otevřete tento soubor a uložte jej pod jiným názvem. 2 Rozhodněte, kde na ploše se mají tato dvě tlačítka zobrazit. Jedno tlačítko slouží ke spuštění animace a druhé
k přechodu do portfolia autora nebo na úvodní stránku. V případě potřeby pro tento nový obsah uvolněte nebo přidejte další prostor na ploše. Pokud animace dosud nemá spouštěcí obrazovku, můžete ji vytvořit na prvním snímku. V takovém případě zřejmě budete chtít animaci posunout, aby začínala od snímku 2 nebo později. 3 Přidejte novou vrstvu nad ostatní vrstvy v časové ose a pojmenujte ji tlačítka. V této vrstvě se budou přidávat
tlačítka. 4 Přidejte novou vrstvu nad vrstvu tlačítek a pojmenujte ji actions. V této vrstvě přidáte do aplikace kód
ActionScript.
Vytváření a přidávání tlačítek Následně zřejmě přidáte a rozmístíte tlačítka tvořící jádro interaktivní aplikace.
Poslední aktualizace 12.5.2011
18
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Začínáme s jazykem ActionScript
Vytvoření a přidání tlačítek do souboru FLA: 1 Pomocí nástrojů kreslení vytvořte vizuální vzhled prvního tlačítka (tlačítko přehrávání) na vrstvě tlačítek. Například můžete nakreslit vodorovný ovál s textem nad ním. 2 Pomocí nástroj výběru vyberte všechny součásti grafiky jednoho tlačítka. 3 V hlavní nabídce zvolte Změnit > Převést na symbol. 4 V dialogovém okně zvolte jako typ symbolu Tlačítko, zadejte název a klepněte na tlačítko OK. 5 S vybraným tlačítkem Inspektor vlastností stanoví pro tlačítko název instance playButton. 6 Opakujte kroky 1 až 5 a vytvořte tlačítko, které přesune uživatele na domovskou stránku autora. Pojmenujte toto
tlačítko homeButton.
Zápis kódu Kód ActionScript pro tuto aplikaci lze rozdělit do tří souborů funkčnosti, i když vše bude zadáváno na jednom místě. Kód provádí následující tři věci:
• Zastavit přehrávací hlavu, jakmile se soubor SWF načte (když přehrávací hlava najede na snímek 1). • Naslouchat události, která spustí přehrávání souboru SWF, když uživatel klepne na tlačítko přehrávání. • Naslouchat události, která odešle prohlížeč na příslušnou stránku URL, když uživatel klepne na tlačítko výchozí webové stránky autora. Vytvoření kódu, který zastaví přehrávací hlavu po najetí na snímek 1: 1 Zvolte klíčový snímek jako snímek 1 vrstvy akcí. 2 Otevřete panel Akce z hlavní nabídky vybráním možnosti Okno > Akce. 3 V panelu Skript zadejte následující kód: stop();
Zapsání kódu, který spustí animaci, když klepnete na tlačítko přehrávání: 1 Na konci kódu zadaného v předchozích krocích přidejte dvě prázdné řádky. 2 Na konec skriptu zadejte následující kód: function startMovie(event:MouseEvent):void { this.play(); }
Tento kód definuje funkci nazvanou startMovie(). Když zavoláte funkci startMovie(), způsobí spuštění přehrávání hlavní časové osy. 3 Na řádku za kódem přidaným v předchozím kroku zadejte tento řádek kódu: playButton.addEventListener(MouseEvent.CLICK, startMovie);
Tento řádek kódu registruje funkci startMovie() jako posluchače pro událost click tlačítka playButton. Jinými slovy, kdykoliv klepnete na tlačítko pojmenované playButton, je zavolána funkce startMovie(). Chcete-li zapsat kód pro přesměrování prohlížeče na adresu URL, když je klepnuto na tlačítko výchozí stránky: 1 Na konci kódu zadaného v předchozích krocích přidejte dvě prázdné řádky. 2 Na konec skriptu zadejte následující kód:
Poslední aktualizace 12.5.2011
19
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Začínáme s jazykem ActionScript
function gotoAuthorPage(event:MouseEvent):void { var targetURL:URLRequest = new URLRequest("http://example.com/"); navigateToURL(targetURL); }
Tento kód definuje funkci nazvanou gotoAuthorPage(). Tato funkce nejprve vytvoří instanci třídy URLRequest představující adresu URL http://example.com/. Ta potom předá tuto adresu URL funkci navigateToURL(), následkem čehož prohlížeč uživatele tuto adresu URL otevře. 3 Na řádku za kódem přidaným v předchozím kroku zadejte tento řádek kódu: homeButton.addEventListener(MouseEvent.CLICK, gotoAuthorPage);
Tento řádek kódu registruje funkci gotoAuthorPage() jako posluchače pro událost click tlačítka homeButton. Jinými slovy, kdykoliv klepnete na tlačítko pojmenované homeButton, je zavolána funkce gotoAuthorPage().
Testování aplikace Nyní je aplikace plně funkční. Otestujme ji a přesvědčme se o tom. Testování aplikace: 1 V hlavní nabídce zvolte Ovládání > Testovat film. Aplikace Flash Professional vytvoří soubor SWF a otevře jej v okně Flash Player. 2 Vyzkoušejte obě tlačítka a ujistěte se, že provádějí přesně ty činnosti, které zamýšlíte. 3 Pokud tlačítka nepracují, měli byste ověřit následující:
• Mají obě tlačítka odlišné názvy instancí? • Volají metody addEventListener() použití stejných názvů, jako jsou názvy instancí tlačítek? • Jsou použité správné názvy událostí ve volání metody addEventListener()? • Je specifikován správný parametr pro každou funkci? (Obě metody by měly mít jeden parametr s datovým typem MouseEvent.) Všechny tyto chyby, jakož i většina ostatních možných chyb, vedou k zobrazení chybové zprávy. Chybová zpráva se může zobrazit buďto po zvolení příkazu Testovat film, nebo při kliknutí na toto tlačítko během testování projektu. Na panelu Chyby kompilátoru vyhledejte chyby kompilátoru (ty, k nimž dochází při prvním zvolení příkazu Testovat film). Na panelu Výstupy zkontrolujte chyby běhu programu, ke kterým dochází během přehrávání obsahu, např. při kliknutí na tlačítko.
Vytváření aplikací v jazyce ActionScript Proces psaní kódu v jazyce ActionScript a vytváření aplikace zahrnuje více než jenom znalost syntaxe a názvů tříd, které použijete. Tato dvě témata popisuje většina dokumentace řešení Flash Platform (syntaxe a použití tříd jazyka ActionScript). Avšak k vytvoření aplikace v jazyce ActionScript bude rovněž třeba znát například následující informace:
• Jaké programy lze použít k psaní kódu v jazyce ActionScript. • Jak se kód v jazyce ActionScript organizuje? • Jak se vkládá kód v jazyce ActionScript do aplikace? • Podle jakých kroků se postupuje při vyvíjení aplikace v jazyce ActionScript?
Poslední aktualizace 12.5.2011
20
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Začínáme s jazykem ActionScript
Možnosti organizování kódu Kód jazyka ActionScript 3.0 můžete použít pro cokoliv, od jednoduchých grafických aplikací, až po složité systém zpracování transakcí klient-server. V závislosti na typu vytvářené aplikace použijte jeden nebo několik těchto různých způsobů zahrnutí kódu ActionScript do projektu. Uložení kódu do snímků časové osy aplikace Flash Professional Ve vývojovém prostředí aplikace Flash Professional lze přidat kód ActionScript ke kterémukoliv snímku v časové ose. Tento kód bude vykonán při přehrávání filmu, když přehrávací hlava najede na daný snímek. Umístění kódu ActionScript dovnitř snímků poskytuje jednoduchý způsob, jak lze přidávat chování do aplikací vytvořených v aplikaci Flash Professional. Můžete přidat kód ke kterémukoliv snímku v hlavní časové ose nebo ke kterémukoliv snímku v časové ose kteréhokoliv symbolu MovieClip. Tato flexibilita však není zdarma. Když vytváříte větší aplikace, snadno ztratíte povědomí o tom, které snímky obsahují které skripty. To může po čase způsobit obtížnější údržbu aplikace. Mnoho vývojářů zjednodušuje organizaci kódu ActionScript v aplikaci Flash Professional vložením kódu pouze do prvního snímku časové osy, nebo do určité vrstvy dokumentu Flash. To usnadňuje lokalizaci a údržbu kódu v souborech FLA aplikace Flash. Nicméně stejný kód nelze použít v jiném projektu aplikace Flash Professional bez toho, aby byl kód zkopírován a vložen do nového souboru. Aby bylo použití kódu jazyka ActionScript snazší v budoucnu v dalších projektech aplikace Flash Professional, uložte kód do externích souborů jazyka ActionScript (textové soubory s příponou .as). Vkládání kódu do souborů Flex MXML Ve vývojovém prostředí aplikace Flex, např. Flash Builder, lze zahrnout kód jazyka ActionScript do tagu v souboru Flex MXML. Nicméně použití této techniky může přidat velkým projektům na složitosti a znesnadnit použití stejného kódu v jiném projektu Flex. Aby bylo použití kódu jazyka ActionScript v dalších projektech Flex v budoucnu snazší, uložte kód do externích souborů jazyka ActionScript. Poznámka: Lze definovat zdrojový parametr pro tag . Pomocí zdrojového parametru lze „importovat“ kód jazyka ActionScript z externího souboru, jako kdyby byl vepsán přímo v tagu . Použitý zdrojový soubor však nemůže definovat vlastní třídu, což omezuje jeho opakovatelnou použitelnost. Uložení kódu v souborech ActionScript Pokud projekt zahrnuje velkou část v kódu ActionScript, nejlepším způsobem organizace kódu je jeho oddělení do samostatných souborů ActionScript (textové soubory s příponou .as). Soubor ActionScript může být strukturován jedním ze dvou způsobů, v závislosti na tom, jak jej zamýšlíte použít v aplikaci.
• Nestrukturovaný kód ActionScript: řádky kódu ActionScript, včetně definic příkazů nebo funkcí, zapsané jako by byly zadány přímo do skriptu časové osy či souboru MXML. Kód ActionScript zapsaný tímto způsobem je přístupný v jazyce ActionScript pomocí příkazu include, nebo v jazyce Flex MXML pomocí tagu <mx:Script>. Příkaz include jazyka ActionScript říká kompilátoru, aby na určité místo a v daném rozsahu ve skriptu zahrnul obsah externího souboru jazyka ActionScript. Výsledek je stejný, jako kdyby tam byl kód zadán přímo. V jazyce MXML se pomocí tagu s atributem zdroje určuje externí kód ActionScript, který kompilátor načte v dané chvíli do aplikace. Například následující tag načte externí soubor jazyka ActionScript s názvem Box.as:
• Definice třídy ActionScript: definice třídy ActionScript, včetně definic metody a vlastností.
Poslední aktualizace 12.5.2011
21
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Začínáme s jazykem ActionScript
Při definování třídy lze získat přístup ke kódu ActionScript v této třídě vytvořením instance dané třídy a použitím jejích vlastností, metod a událostí. Použití vlastních tříd je stejné jako použití vestavěných tříd ActionScript a vyžaduje dvě části:
• Použití příkazu import pro specifikování úplného názvu třídy, aby kompilátor jazyka ActionScript věděl, kde jej má nalézt. Chcete-li například použít třídu MovieClip v jazyce ActionScript, importujte ji pomocí jejího úplného názvu včetně balíku a třídy: import flash.display.MovieClip;
Alternativně můžete importovat balík, který obsahuje třídu MovieClip, což je ekvivalent pro zápis samostatného příkazu import pro každou třídu v balíku. import flash.display.*;
Jedinou výjimkou z pravidla, že třída musí být importována, aby ji bylo možné použít v kódu, jsou třídy nejvyšší úrovně. Tyto třídy nejsou definovány v balíku.
• Zadejte kód, který výslovně používá název třídy. Deklarujte například proměnnou s touto třídou jako jejím datovým typem a vytvořte instanci této třídy, jež bude v proměnné uložena. Použitím třídy v kódu ActionScript sdělujete kompilátoru, aby načetl definici dané třídy. Například pro externí třídu s názvem Box by tento příkaz vytvořil instanci třídy Box: var smallBox:Box = new Box(10,20);
Když kompilátor poprvé narazí na odkaz na třídu Box, prohledá dostupný zdrojový kód, aby nalezl definici třídy Box.
Výběr správného nástroje Pro psaní a úpravu kódu ActionScript lze použít jeden z mnoha nástrojů (nebo několik nástrojů dohromady). Flash Builder Aplikace Adobe Flash Builder je nejlepší nástroj pro vytváření projektů s architekturou Flex, nebo projektů sestávajících především z kódu ActionScript. Aplikace Flash Builder rovněž zahrnuje plnohodnotný editor jazyka ActionScript, jakož i možnost vizuálního rozvržení a upravování jazyka MXML. Lze ji použít k vytváření projektů s architekturou Flex nebo projektů zahrnujících pouze jazyk ActionScript. Architektura Flex poskytuje několik výhod, včetně bohaté sady předem vytvořených ovládacích prvků uživatelského rozhraní, flexibilních ovládacích prvků dynamického uspořádání a vestavěných mechanismů pro práci s externími datovými zdroji a propojování externích dat s prvky uživatelského rozhraní. Nicméně kvůli množství dalšího kódu nezbytného pro zajištění těchto funkcí mohou mít projekty používající architekturu Flex větší soubory SWF než jejich protějšky, které architekturu Flex nepoužívají. Aplikaci Flash Builder použijte, pokud vytváříte plnohodnotné, výkonné, datově řízené internetové aplikace s architekturou Flex. Použijte ji, jestliže chcete upravovat kód ActionScript, upravovat kód MXML a provádět vizuální rozvržení aplikace, to vše v rámci jediného nástroje. Řada uživatelů aplikace Flash Professional, kteří vytvářejí projekty zahrnující velké množství kódu ActionScript, používá aplikaci Flash Professional k vytváření vizuálních datových zdrojů a aplikaci Flash Builder jako editor pro kód ActionScript.
Poslední aktualizace 12.5.2011
22
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Začínáme s jazykem ActionScript
Flash Professional Kromě grafických a animačních schopností zahrnuje aplikace Flash Professional nástroje pro práci s kódem ActionScript. Kód může být připojený k elementům v souboru FLA nebo v externích souborech obsahujících pouze jazyk ActionScript. Aplikace Flash Professional je ideální pro projekty obsahující z podstatné části animaci či video. Je užitečná, když chcete většinu grafických datových zdrojů vytvářet sami. Dalším důvodem k použití aplikace Flash Professional při vyvíjení projektu v jazyce ActionScript je vytváření vizuálních datových zdrojů a zapisování kódu ve stejné aplikaci. Aplikace Flash Professional rovněž zahrnuje předem vytvořené komponenty uživatelského rozhraní. Použitím těchto komponent lze docílit menší velikosti souborů SWF a pomocí vizuálních nástrojů je možné upravovat jejich vzhled v daném projektu. Aplikace Flash Professional zahrnuje dva nástroje pro zápis kódu v jazyce ActionScript:
• Panel Akce: dostupný při práci na souboru FLA. tento panel umožňuje zapisovat kód ActionScript připojený je snímkům v časové ose.
• Okno Skript: okno Skript je vyhrazeným textovým editorem pro práci s kódem v jazyce ActionScript (soubory .as). Editor jazyka ActionScript od jiných výrobců Jelikož jsou soubory jazyka ActionScript (.as) uloženy jako jednoduché textové soubory, lze k psaní souborů jazyka ActionScript použít jakýkoliv program schopný editace prostého textu. Kromě produktů ActionScript od Adobe existuje několik textových editorů třetích stran, se specifickými schopnostmi práce s kódem ActionScript. Soubor MXML nebo třídy ActionScript můžete zapisovat pomocí kteréhokoliv textového editoru. Pak můžete z těchto souborů vytvořit aplikaci pomocí sady Flex SDK. Projekt může využívat architekturu Flex, nebo se může jednat o aplikaci obsahující pouze jazyk ActionScript. Někteří vývojáři případně používají aplikaci Flash Builder nebo editor jazyka ActionScript jiného výrobce k zápisu tříd ActionScript v kombinaci s aplikací Flash Professional k vytváření grafického obsahu. K použití editoru jazyka ActionScript jiného výrobce existují například následující důvody:
• Dáváte přednost zapisování kódu ActionScript v samostatném programu a navrhování vizuálních elementů v aplikaci Flash Professional.
• Používáte aplikaci pro programování v jiném jazyce než ActionScript (například vytváření stránek HTML nebo vytváření aplikací v jiném programovacím jazyce) a chcete používat stejnou aplikaci také pro zápis kódu v jazyce ActionScript.
• Chcete vytvořit projekty obsahující pouze jazyk ActionScript nebo projekty Flex pomocí sady Flex SDK, bez použití aplikace Professional nebo Flash Builder. Některé vhodné editory programového kódu se specifickou podporou jazyka ActionScript zahrnují:
• Adobe Dreamweaver® CS4 • ASDT • FDT • FlashDevelop • PrimalScript • SE|PY • TextMate (s balíky ActionScript a Flex)
Poslední aktualizace 12.5.2011
23
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Začínáme s jazykem ActionScript
Proces vývoje kódu v jazyce ActionScript Bez ohledu na to, zda je projekt v jazyce ActionScript velký nebo malý, proces návrhu a vývoje aplikace celou práci zefektivní. Následující kroky popisují základní proces vývoje aplikace pomocí ActionScript 3.0: 1 Navrhněte aplikaci.
Před započetím vývoje aplikaci vhodným způsobem popište. 2 Sestavte kód v jazyce ActionScript 3.0.
Kód ActionScript lze vytvořit pomocí aplikací Flash Professional, Flash Builder, Dreamweaver nebo textového editoru. 3 Vytvořte projekt Flash nebo Flex, který spustí váš kód.
V aplikaci Flash Professional vytvořte soubor FLA, zadejte nastavení publikování, přidejte do aplikace komponenty uživatelského rozhraní a vytvořte odkaz na kód ActionScript. V architektuře Flex definujte aplikaci, pomocí jazyka MXML přidejte komponenty uživatelského rozhraní a vytvořte odkaz na kód ActionScript. 4 Publikujte a otestujte svou aplikaci ActionScript.
V rámci testování aplikace spusťte aplikaci ze svého vývojového prostředí a ujistěte se, že provádí všechny zamýšlené operace. Všimněte si, že není nutné provádět tyto kroky v přesně uvedeném pořadí, nebo dokončit jeden krok před započetím jiného. Můžete například navrhnout jednu obrazovku aplikace (krok 1), pak vytvořit grafiku, tlačítka atd. (krok 3) a až poté napsat kód v jazyce ActionScript (krok 2) a provést testování (krok 4). Nebo můžete navrhnout část, pak přidat jedno tlačítko nebo prvek rozhraní, zapsat kód v jazyce ActionScript pro každý z těchto prvků a otestovat jej v daném provedení. Je užitečné si tyto čtyři fáze procesu vývoje zapamatovat. Nicméně při vývoji v reálném prostředí je mnohem efektivnější přeskakovat mezi těmito fázemi podle potřeby.
Vytváření vlastních tříd Proces vytváření tříd pro použití ve vašich projektech může vypadat skličující. Obtížnější částí vytvoření třídy je však její návrh jejích metod, vlastností a událostí.
Strategie vytváření třídy Téma objektově orientovaného návrhu je komplexní. Celé kariéry mnoha osob byly věnovány akademickému studiu a profesionální praxi v této disciplíně. Existuje však několik doporučovaných přístupů. které mohou v začátcích pomoci. 1 Přemýšlejte o úloze, kterou hrají instance této třídy v dané aplikaci. Obecně objekty slouží jedné z těchto tří rolí:
• Objekt Value: tyto objekty slouží především jako kontejnery dat. Pravděpodobně mají řadu vlastností a méně metod (nebo někdy žádné metody). Obecně jsou vyjádřením kódu jasně definovaných položek. Například aplikace pro přehrávání hudby by mohla zahrnovat třídu Song představující jedinou skladbu a třídu Playlist představující koncepční skupinu skladeb.
• Objekt Display: Tyto objekty se ve skutečnosti zobrazují na obrazovce. Patří k nim prvky uživatelského rozhraní, například rozevírací seznam nebo indikace stavu, grafické prvky, jako jsou příšery ve video hře atd.
Poslední aktualizace 12.5.2011
24
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Začínáme s jazykem ActionScript
• Struktura aplikace: tyto objekty zajišťují širokou škálu podpůrných úloh v logice a zpracování prováděných aplikacemi. Můžete například vytvořit objekt, který bude provádět určité výpočty v biologické simulaci. Můžete vytvořit jeden objekt, který bude mít na starosti synchronizaci hodnot mezi volicím ovladačem a indikací hlasitosti v aplikaci pro přehrávání hudby. Další objekt může spravovat pravidla ve videohře. Nebo můžete vytvořit třídu, která načte uložený obraz do kreslicí aplikace. 2 Rozhodněte, jakou specifickou funkčnost musí třída mít. Různé typy funkcí se často stávají metodami třídy. 3 Pokud má třída sloužit jako objekt hodnoty, rozhodněte se, která data budou instance zahrnovat. Tyto položky jsou
vhodnými kandidáty pro vlastnosti. 4 Protože třída je navrhována specificky pro váš projekt, nejdůležitější je poskytnout funkčnost, kterou vyžaduje vaše
aplikace. Zkuste si odpovědět na následující otázky:
• Jaké kusy informací aplikace ukládá, sleduje a zpracovává? Odpověď na tuto otázku vám pomůže určit potřebné objekty hodnot a vlastnosti.
• Jaké sady akcí aplikace provádí? Co se stane například při prvním načtení aplikace, při stisknutí určitého tlačítka, při ukončení přehrávání filmu atd.? Toto jsou vhodní kandidáti na metody. Také to mohou být vlastnosti, pokud „akce“ zahrnují změnu jednotlivých hodnot.
• Jaké informace vyžaduje jakákoliv daná akce, aby byla provedena? Tyto části informací se stávají parametry metody.
• Když aplikace pokračuje v činnosti, kterou má vykonávat, k jakým změnám dojde ve vaší třídě, o nichž budou jiné části této aplikace muset vědět? Toto jsou vhodní kandidáti na události. 5 Existuje již nějaký objekt, který by se podobal požadovanému objektu až na to, že postrádá některé dodatečné
funkce, jež chcete přidat? Zvažte vytvoření podtřídy. (Podtřída je třída, která staví na funkčnosti existující třídy, než aby definovala všechny své funkce.) Chcete-li například vytvořit třídu, jíž je vizuální objekt na obrazovce, použijte jako základ vlastní třídy chování existujícího objektu zobrazení. V takovém případě bude objekt zobrazení (například objekt MovieClip nebo Sprite) základní třídou a vlastní třída bude tuto třídu rozšiřovat.
Zápis kódu pro třídu Jakmile máte návrh vlastní třídy, nebo alespoň určitou představu o tom, jaké informace bude ukládat a jaké akce bude provádět, je vlastní syntaxe zápisu třídy poměrně přímočará. Zde jsou minimální kroky, které byste měli vytvořit ve vlastní třídě ActionScript: 1 Otevřete v programu textového editoru jazyka ActionScript nový textový dokument. 2 Zadáním příkazu classdefinujte název třídy. Chcete-li přidat příkaz class, zadejte slova public class
a následně název třídy. Přidejte levou a pravou složenou závorku, mezi nimiž bude uzavřen obsah třídy (definice metod a vlastností). Například: public class MyClass { }
Slovo public označuje, že třída může být přístupná z jiného libovolného kódu. Jiné alternativy naleznete v kapitole Atributy jmenného prostoru řízení přístupu. 3 Zadáním příkazu package určete název balíku obsahujícího danou třídu. Syntaxí je slovo package, po kterém
následuje úplný název balíku, za nímž je umístěna levá a pravá složená závorka kolem bloku příkazu class. Změňte například kód v předchozím kroku na následující:
Poslední aktualizace 12.5.2011
25
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Začínáme s jazykem ActionScript
package mypackage { public class MyClass { } }
4 Definujte každou vlastnost ve třídě pomocí příkazu var v těle třídy. Syntaxe je stejná jako při deklarování kterékoliv
proměnné (s přidáním modifikátoru public). Například přidáním těchto řádek mezi levou a pravou složenou závorku definice třídy se vytvoří vlastnosti pojmenované textProperty, numericProperty a dateProperty: public var textProperty:String = "some default value"; public var numericProperty:Number = 17; public var dateProperty:Date;
5 Definujte každou metodu ve třídě pomocí stejné syntaxe, kterou použijete pro definování funkce. Například:
• Chcete-li vytvořit metodu myMethod(), zadejte: public function myMethod(param1:String, param2:Number):void { // do something with parameters }
• Chcete-li vytvořit konstruktor (speciální metoda, která je volaná jako součást procesu vytváření instance třídy), vytvoření metody, jejíž název odpovídá přesně názvu třídy: public function MyClass() { // do stuff to set initial values for properties // and otherwise set up the object textVariable = "Hello there!"; dateVariable = new Date(2001, 5, 11); }
Pokud do třídy nezahrnete metodu konstruktoru, kompilátor automaticky vytvoří v dané třídě prázdný konstruktor. (Jinými slovy konstruktor bez jakýchkoliv parametrů a příkazů.) Kromě toho lze definovat i několik dalších elementů třídy. Tyto elementy jsou složitější.
• Zpřístupňovače jsou speciální přechody mezi metodou a vlastností. Při zápisu kódu pro definování třídy zapisujete zpřístupňovač jako metodu. Můžete provádět několik akcí a nikoliv jen čtení nebo přiřazení hodnoty, což je to jediné, co lze provádět při definování vlastnosti. Nicméně když vytváříte instanci vlastní třídy, zacházíte se zpřístupňovačem jako s vlastností a používáte název ke čtení nebo přiřazení hodnoty.
• Události v jazyce ActionScript nejsou definované pomocí specifické syntaxe. Místo toho definujete události ve třídě pomocí funkcí třídy EventDispatcher.
Další témata nápovědy Zpracování událostí
Příklad: Vytváření základních aplikací Jazyk ActionScript 3.0 lze použít v řadě prostředí pro vývoj aplikací, včetně nástrojů Flash Professional a Flash Builder, nebo v libovolném textovém editoru.
Poslední aktualizace 12.5.2011
26
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Začínáme s jazykem ActionScript
Tento příklad prochází kroky při vytváření a zlepšování jednoduché aplikace v kódu ActionScript 3.0 pomocí aplikace Flash Professional nebo Flash Builder. Vytvořená aplikace představuje jednoduchý vzor k použití externích souborů třídy ActionScript 3.0 v aplikacích Flash Professional a Flex.
Návrh aplikace ActionScript Tato vzorová aplikace v jazyce ActionScript je standardní aplikace s nápisem „Hello World“, takže její návrh je jednoduchý:
• Aplikace se nazývá Hello World. • Zobrazuje jediné textové pole se slovy „Hello World!“. • Aplikace používá jedinou objektově orientovanou třídu s názvem Greeter. Tento návrh umožňuje použití třídy z projektu Flash Professional nebo Flex.
• V tomto příkladu nejprve vytvoříte základní verzi aplikace. Potom přidáte funkce, pomocí nichž uživatel zadá jméno uživatele a aplikace zkontroluje jméno podle seznamu známých uživatelů. Se stručným definováním můžete začít vytvářet aplikaci samotnou.
Vytváření projektu Hello World a třídy Greeter Návrh příkazu pro aplikaci Hello World říká, že kód je snadno opakovaně použitelný. K dosažení tohoto cíle používá aplikace jedinou objektově orientovanou třídu s názvem Greeter. Tato třída se používá z aplikace vytvořené ve vývojovém nástroji Flash Builder nebo Flash Professional. Chcete-li vytvořit projekt Hello World a třídu Greeter ve vývojovém prostředí Flex: 1 V aplikaci Flash Builder zvolte Soubor > Nový > Projekt Flex. 2 Zadejte HelloWorld jako název projektu. Ujistěte se, že je typ aplikace nastaven na „Web (pro přehrávač Adobe
Flash Player)“, a potom klikněte na tlačítko Dokončit. Aplikace Flash Builder vytvoří projekt a zobrazí jej v průzkumníku balíku. Projekt již standardně obsahuje soubor pojmenovaný HelloWorld.mxml a tento soubor je otevřen v editoru. 3 Chcete-li nyní vytvořit soubor vlastní třídy jazyka ActionScript v aplikaci Flash Builder, vyberte položky Soubor >
Nový > Třídy jazyka ActionScript. 4 V dialogovém okně Nová třída jazyka ActionScript zadejte do pole Název pro název třídy výraz Greeter a poté
klepněte na tlačítko Dokončit. Zobrazí se nové editační okno ActionScript. Pokračujte se zapisováním kódu do třídy Greeter. Postup při vytváření třídy Greeter v aplikaci Flash Professional: 1 V aplikaci Flash Professional zvolte Soubor > Nový. 2 V dialogovém okně Nový dokument zvolte soubor ActionScript a klepněte na tlačítko OK.
Zobrazí se nové editační okno ActionScript. 3 Vyberte Soubor > Uložit. Vyberte složku pro uložení aplikace, pojmenujte soubor ActionScript Greeter.as a
klepněte na tlačítko OK. Pokračujte se zapisováním kódu do třídy Greeter.
Poslední aktualizace 12.5.2011
27
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Začínáme s jazykem ActionScript
Zapisování kódu do třídy Greeter Třída Greeter definuje objekt Greeter, který použijete v aplikaci HelloWorld. Chcete-li zapsat kód do třídy Greeter: 1 Zadejte do nového pole následující kód. (Některé části kódu mohly být přidány za vás.): package { public class Greeter { public function sayHello():String { var greeting:String; greeting = "Hello World!"; return greeting; } } }
Třída Greeter zahrnuje jednu metodu sayHello(), která vrací řetězec říkající „Hello World!“. 2 Vyberte Soubor > Uložit a uložte tento soubor ActionScript.
Třída Greeter je nyní připravena k použití v aplikaci.
Vytváření aplikace, která používá kód ActionScript Třída Greeter, kterou jste vytvořili, definuje samostatný soubor softwarových funkcí, ale nereprezentuje kompletní aplikaci. Chcete-li třídu použít, vytvořte dokument aplikace Flash Professional nebo projekt Flex. Kód potřebuje instanci třídy Greeter. Zde je popsáno, jak použijete třídu Greeter ve své aplikaci. Postup při vytváření aplikace ActionScript pomocí vývojového prostředí Flash Professional: 1 Zvolte Soubor > Nový. 2 V dialogovém okně Nový dokument zvolte soubor Flash (ActionScript 3.0) a klepněte na tlačítko OK.
Zobrazí se nové okno dokumentu. 3 Vyberte Soubor > Uložit. Zvolte stejnou složku, která obsahuje soubor třídy Greeter.as, pojmenujte dokumentu
Flash HelloWorld.fla a klepněte na tlačítko OK. 4 V paletě nástrojů aplikace Flash Professional zvolte nástroj Text. Táhnutím přes plochu definujte nové textové pole
široké asi 300 obrazových bodů a vysoké asi 100 obrazových bodů. 5 S textovým polem stále vybraným na ploše nastavte v panelu Vlastnosti typ textu na „Dynamický text“. Jako název
instance textového pole zadejte mainText. 6 Klikněte na první snímek v hlavní časové ose. Vyberte položky Okna > Akce a otevřete panel Akce. 7 V panelu Akce zadejte následující skript: var myGreeter:Greeter = new Greeter(); mainText.text = myGreeter.sayHello();
8 Uložte soubor.
Pokračujte v části Publikování a testování aplikace ActionScript.
Poslední aktualizace 12.5.2011
28
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Začínáme s jazykem ActionScript
Postup při vytváření aplikace ActionScript pomocí vývojového prostředí Flash Builder: 1 Otevřete soubor HelloWorld.mxml a přidejte kód odpovídající následujícímu výčtu: <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/halo" minWidth="1024" minHeight="768"" creationComplete="initApp()"> <s:layout> <s:VerticalLayout/> <s:TextArea id="mainTxt" width="400"/>
Tento projekt rozhraní Flex zahrnuje čtyři tagy jazyka MXML:
• Tag <s:Application>, který definuje kontejner Application. • Tag <s:layout>, který definuje styl rozvržení (svislé rozvržení) pro tag Application. • Tag , který zahrnuje části kódu jazyka ActionScript. • Tag <s:TextArea>, který definuje pole k zobrazení textové zprávy uživateli. Kód v tagu definuje metodu initApp(). Tato metoda je volána při načtení aplikace. Metoda initApp() nastaví textovou hodnotu mainTxt TextArea na řetězec „Hello World!“ vrácený metodou sayHello() uživatelské třídy Greeter, kterou jste právě napsali. 2 Vyberte Soubor > Uložit a uložte aplikaci.
Pokračujte v části Publikování a testování aplikace ActionScript.
Publikování a testování aplikace ActionScript Vývoj softwaru je iterační proces. Napíšete část kódu, pokusíte se jej zkompilovat a upravíte kód tak, až je zkompilován čistě. Spustíte sestavenou aplikaci a otestujete ji, zda splňuje zamýšlený návrh. V opačném případě budete kód znovu upravovat, dokud jej nebude splňovat. Vývojová prostředí Flash Professional a Flash Builder nabízejí mnoho způsobů, jak publikovat, testovat a ladit aplikace. Zde jsou uvedeny některé základní kroky pro testování aplikace HelloWorld v jednotlivých prostředích.
Poslední aktualizace 12.5.2011
29
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Začínáme s jazykem ActionScript
Postup při publikování a testování aplikace ActionScript ve vývojovém prostředí Flash Professional: 1 Publikujte svou aplikaci a sledujte chyby kompilace. Ve vývojovém nástroji Flash Professional zvolte Ovládání > Testovat film a zkompilujte kód v jazyce ActionScript a spusťte aplikaci HelloWorld. 2 Jestliže se při testování aplikace zobrazují v okně Výstup jakékoliv chyby či upozornění, opravte tyto chyby
v souboru HelloWorld.fla nebo HelloWorld.as. Potom znovu zkuste aplikaci otestovat. 3 Pokud žádné chyby během kompilace nenastanou, zobrazí se okno přehrávače Flash Player s aplikací Hello World.
Právě jste vytvořili jednoduchou, objektově orientovanou aplikaci, která využívá kódu ActionScript 3.0. Pokračujte v části Zlepšení aplikace HelloWorld. Postup při publikování a testování aplikace ActionScript ve vývojovém prostředí Flash Builder: 1 Vyberte položky Spustit > Spustit aplikaci HelloWorld. 2 Aplikace HelloWorld se spustí.
• Jestliže se při testování aplikace zobrazují v okně Výstup jakékoliv chyby či upozornění, opravte je v souboru HelloWorld.mxml nebo Greeter.as. Potom znovu zkuste aplikaci otestovat.
• Pokud se žádné chyby kompilace nevyskytnou, otevře se okno prohlížeče, zobrazující aplikaci HelloWorld. Měl by být zobrazen text „Hello World!“ . Právě jste vytvořili jednoduchou, objektově orientovanou aplikaci, která využívá kódu ActionScript 3.0. Pokračujte v části Zlepšení aplikace HelloWorld.
Zlepšení aplikace HelloWorld Chcete-li aplikaci poněkud vylepšit a učinit zajímavější, měli byste se nyní dotázat na jméno uživatele a ověřit jej vůči předdefinovanému seznamu jmen. Nejprve aktualizujte třídu Greeter a přidejte novou funkci. Pak aktualizujte aplikaci, aby novou funkci použila. Aktualizace souboru Greeter.as: 1 Otevřete soubor Greeter.as. 2 Změňte obsah souboru tak, aby byl následující (nové a změněné řádky jsou zobrazeny tučným písmem). package { public class Greeter { /** * Defines the names that receive a proper greeting. */ public static var validNames:Array = ["Sammy", "Frank", "Dean"]; /** * Builds a greeting string using the given name. */ public function sayHello(userName:String = ""):String { var greeting:String; if (userName == "") { greeting = "Hello. Please type your user name, and then press " + "the Enter key."; }
Poslední aktualizace 12.5.2011
30
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Začínáme s jazykem ActionScript
else if (validName(userName)) { greeting = "Hello, " + userName + "."; } else { greeting = "Sorry " + userName + ", you are not on the list."; } return greeting; } /** * Checks whether a name is in the validNames list. */ public static function validName(inputName:String = ""):Boolean { if (validNames.indexOf(inputName) > -1) { return true; } else { return false; } } } }
Třída Greeter má nyní několik nových vlastností:
• Pole validNames uvádí seznam s platnými uživatelskými jmény. Pole se inicializuje tak, aby po načtení třídy Greeter otevřelo seznam tří jmen.
• Metoda sayHello() nyní přijme uživatelské jméno a změní pozdrav na základě některých podmínek. Pokud je userName prázdný řetězec (""), vlastnosti greeting je nastaven na zobrazení výzvy uživateli, aby zadal jméno.
Pokud je uživatelské jméno platné, pozdrav bude "Hello, userName." Nakonec, pokud není ani jedna z těchto dvou podmínek, proměnná greeting se nastaví na "Sorry userName, you are not on the list."
• Metoda validName() vrátí hodnotu true, pokud je nalezeno inputName v poli validNames, nebo hodnotu false, pokud nalezeno není. Příkaz validNames.indexOf(inputName) kontroluje každý řetězec v poli validNames proti řetězci inputName. Metoda Array.indexOf() vrací indexovou polohu první instance objektu v poli. Není-li objekt v poli nalezen, vrátí hodnotu -1.
Potom upravte soubor aplikace, který odkazuje na třídu ActionScript. Postup při úpravě aplikace pomocí vývojového prostředí Flash Professional: 1 Otevřete soubor HelloWorld.fla. 2 Změňte skript ve snímku 1 tak, aby prázdný řetězec ("") byl předán metodě sayHello() třídy Greeter: var myGreeter:Greeter = new Greeter(); mainText.text = myGreeter.sayHello("");
3 V paletě nástrojů zvolte nástroj Text. Vytvořte na ploše dvě nová textová pole. Umístěte je vedle sebe přímo pod
existující textové pole mainText. 4 Do prvního nového textového pole, což je popis, zadejte text Jméno uživatele:.
Poslední aktualizace 12.5.2011
31
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Začínáme s jazykem ActionScript
5 Vyberte druhé nové textové pole a v Inspektoru vlastností zvolte InputText jako typ textového pole. Jako typ řádky
zvolte jednotlivou řádku. Jako název instance zadejte textIn. 6 Klepněte na první snímek v hlavní časové ose. 7 V panelu Akce přidejte na konec stávajícího skriptu následující řádky: mainText.border = true; textIn.border = true; textIn.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed); function keyPressed(event:KeyboardEvent):void { if (event.keyCode == Keyboard.ENTER) { mainText.text = myGreeter.sayHello(textIn.text); } }
Nový kód přidá následující funkci:
• První dva řádky jednoduše definují okraje dvou textových polí. • Vstupní textové pole, například pole textIn, nastavilo události, které může odeslat. Metoda addEventListener() umožňuje definovat funkci, která se spustí, když nastane typ události. V tomto případě
je touto události stisknutí klávesy.
• Uživatelská funkce keyPressed() kontroluje, zda stisknutou klávesou byla klávesa Enter. Pokud ani, funkce zavolá metodu sayHello() objektu myGreeter a předá text z textového pole textIn jako parametr. Tato metoda vrací řetězec pozdravu na základě předané hodnoty. Vrácený řetězec je pak přiřazen vlastnosti text textového pole mainText. Celý skript pro snímek 1 je následující: var myGreeter:Greeter = new Greeter(); mainText.text = myGreeter.sayHello(""); mainText.border = true; textIn.border = true; textIn.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed); function keyPressed(event:KeyboardEvent):void { if (event.keyCode == Keyboard.ENTER) { mainText.text = myGreeter.sayHello(textIn.text); } }
8 Uložte soubor. 9 Výběrem možností Ovládání > Testovat film spusťte aplikaci.
Po spuštění aplikace budete vyzváni k zadání jména uživatele. Pokud je platné (Sammy, Frank nebo Dean), aplikace zobrazí hlášení s potvrzením „Hello“. Postup při úpravě aplikace pomocí vývojového prostředí Flash Builder: 1 Otevřete soubor HelloWorld.mxml.
Poslední aktualizace 12.5.2011
32
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Začínáme s jazykem ActionScript
2 Potom upravte tag <mx:TextArea>, aby uživatele informoval, že slouží pouze k zobrazení. Změňte barvu pozadí
na světle šedou a nastavte atribut editable na hodnotu false: <s:TextArea id="mainTxt" width="400" backgroundColor="#DDDDDD" editable="false" />
3 Nyní přidejte následující řádky přímo za koncový tag <s:TextArea>. Tyto řádky vytvářejí komponentu TextInput,
která umožňuje uživateli zadat hodnotu jména uživatele: <s:HGroup width="400"> <mx:Label text="User Name:"/> <s:TextInput id="userNameTxt" width="100%" enter="mainTxt.text = myGreeter.sayHello(userNameTxt.text);" />
Atribut enter definuje, co se stane, když uživatel stiskne klávesu Enter v poli userNameTxt. V tomto příkladu kód předá text v poli metodě Greeter.sayHello(). Pozdrav v poli mainTxt se podle toho změní. Soubor HelloWorld.mxml vypadá takto: <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/halo" minWidth="1024" minHeight="768"" creationComplete="initApp()"> <s:layout> <s:VerticalLayout/> <s:TextArea id="mainTxt" width="400" backgroundColor="#DDDDDD" editable="false"/> <s:HGroup width="400"> <mx:Label text="User Name:"/> <s:TextInput id="userNameTxt" width="100%" enter="mainTxt.text = myGreeter.sayHello(userNameTxt.text);" />
4 Uložte upravený soubor HelloWorld.mxml. Vyberte položky Spustit > Spustit aplikaci HelloWorld a spusťte
aplikaci. Po spuštění aplikace budete vyzváni k zadání jména uživatele. Pokud je platné (Sammy, Frank nebo Dean), aplikace zobrazí hlášení s potvrzením „Hello, jméno uživatele“.
Poslední aktualizace 12.5.2011
33
Kapitola 3: Jazyk ActionScript a jeho syntaxe Jazyk ActionScript 3.0 zahrnuje jádro jazyka ActionScript i programovací rozhraní aplikace Adobe Flash Platform (API). Základní jazyk je částí jazyka ActionScript, která definuje syntaxi jazyka i typy dat na nejvyšší úrovni. Jazyk ActionScript 3.0 poskytuje programový přístup k běhovým modulům řešení Adobe Flash Platform: Adobe Flash Player a Adobe AIR.
Přehled jazyka Objekty ležící v jádru jazyka ActionScript 3.0 - tvoří základní stavební bloky. Každá proměnná, kterou deklarujete, každá zapsaná funkce a každá vytvořená instance třídy je objektem. Program jazyka ActionScript 3.0 můžete považovat za skupinu objektů provádějících úlohy, reagujících na události a komunikujících navzájem mezi sebou. Programátoři seznámení s objektově orientovaným programováním (OOP) v jazyce Java nebo C++ mohou považovat objekty za moduly, obsahující dva typy členů: data uložená v členských proměnných nebo vlastnostech, a chování přístupné prostřednictvím metod. Jazyk ActionScript 3.0 definuje objekty podobným ale trochu odlišným způsobem. V jazyce ActionScript 3.0 jsou objekty jednoduše sbírkou vlastností. Tyto vlastnosti jsou kontejnery, které uchovávají nejenom data, ale také funkce nebo jiné objekty. Pokud je funkce tímto způsobem připojená k objektu, nazývá se metodou. Zatímco definice jazyka ActionScript 3.0 se může programátorům jazyků Java nebo C++ zdát poněkud podivná, v praxi definování typů objektů s třídami ActionScript 3.0 bude velmi podobná způsobu, kterým jsou definovány třídy v jazyce Java nebo C++. Rozdíl mezi dvěma definicemi objektu je důležitý při projednávání objektového modelu ActionScript a dalších pokročilých témat, ale ve většině jiných situací znamená termín vlastnosti proměnné členy tříd, což je protiklad metod. Referenční příručka jazyka ActionScript 3.0 pro řešení Adobe Flash Platform například používá termín vlastnosti k označení proměnných nebo vlastností metody pro získání a nastavení. Používá termín metody k popisu funkcí, které jsou součástí třídy. Jedním drobným rozdílem mezi třídou ActionScript a třídami v jazycích Java nebo C++ je to, že v jazyce ActionScript nejsou třídy pouhými abstraktními entitami. Třídy ActionScript jsou vyjádřeny objekty třídy, které ukládají vlastnosti třídy a metody. To umožňuje používat techniky, které se mohou zdát programátorům jazyků Java a C++ podivné, například zahrnutí příkazů nebo spustitelného kódu na horní úrovni třídy nebo balíku. Dalším rozdílem mezi třídami ActionScript a jazyka Java nebo C++ je v tom, že každá třída ActionScript má něco, co se nazývá prototypovýobjekt. V předchozích verzích jazyka ActionScript sloužily prototypové objekty spojené do řetězců prototypů jako základy dědičnosti celé hierarchie třídy. V jazyce ActionScript 3.0 však prototypové objekty hrají jenom malou úlohu v systému dědičnosti. Prototypový objekt může být i nadále užitečný, nicméně jako alternativa statickým vlastnostem a metodám, pokud chcete sdílet vlastnost a její hodnotu mezi všemi instancemi třídy. V minulosti programátoři ActionScript mohli přímo manipulovat s prototypovým řetězcem se zvláštními vestavěnými prvky jazyka. Nyní, když jazyk poskytuje zralejší implementaci programovacího rozhraní založeného na třídách, mnoho z těchto speciálních prvků jazyka, například __proto__ a __resolve, již není jeho součástí. Kromě toho optimalizace mechanismu vnitřní dědičnosti, která poskytuje významné zvýšení výkonu, zabraňuje přímému přístupu k mechanismu dědičnosti.
Poslední aktualizace 12.5.2011
34
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
Objekty a třídy V jazyce ActionScript 3.0 je každý objekt definovaný svou třídou. Třída může být šablonu nebo modrotiskem typu objektu. Definice třídy mohou zahrnovat proměnné a konstanty, které uchovávají datové hodnoty, a metody, které jsou funkcemi obsahujícími chování spojené s danou třídou. Hodnoty uložené ve vlastnostech mohou být primitivní hodnoty nebo jiné objekty. Primitivní hodnoty jsou čísla, řetězce a booleovské hodnoty. Jazyk ActionScript obsahuje několik vestavěných tříd, které jsou součástí jádra jazyka. Některé z těchto vestavěných tříd, například čísla, booleovské hodnoty a řetězce, představují primitivní hodnoty dostupné v jazyce ActionScript. Jiné, např. třídy Array, Math a XML, definují složitější objekty. Všechny třídy, vestavěné nebo definované uživatelem, jsou odvozeny od třídy Object. Pro programátory s předchozí zkušenosti s jazykem ActionScript, je důležité poznamenat, že datový typ Object již není výchozím typem, i když jsou všechny třídy od něj odvozeny. V jazyce ActionScript 2.0 byly následující dva řádky kódu shodné protože neexistovala anotace typu znamenající, že proměnná by byla typu Object: var someObj:Object; var someObj;
Jazyk ActionScript 3.0 však zavádí koncept proměnných bez typu, které mohou být označeny následujícími dvěma způsoby: var someObj:*; var someObj;
Proměnné bez typu nejsou stejné, jako proměnné typu Object. Klíčovým rozdílem je to, že proměnné bez typu mohou uchovávat speciální hodnotu undefined, zatímco proměnná typu Object tuto hodnotu uchovávat nemůže. Můžete definovat své vlastní třídy a to pomocí klíčového slova class. vlastnosti třídy deklarujete třemi způsoby: konstanty mohou být definovány klíčovým slovem const, proměnné mohou být definovány klíčovým slovem var a vlastnosti getter a setter mohou být definovány použitím atributu get a set v deklarování metody. Metody můžete deklarovat klíčovým slovem function. Instanci třídy můžete vytvořit pomocí operátoru new. Následující příklad vytváří instanci třídy Date nazvanou myBirthday. var myBirthday:Date = new Date();
Balíčky a jmenné prostory Balíčky a jmenné prostory jsou související koncepty. Balíčky umožňují spojit definice tříd způsobem, který usnadňuje sdílení kódu a minimalizuje konflikty pojmenování. Jmenné prostory umožňují řídit viditelnost identifikátorů, například názvů vlastnosti a metody, a mohou být použity v kódu bez ohledu na to, zda je umístěn vně nebo uvnitř balíčku. Balíčky umožňují organizovat soubory tříd, jmenné prostory umožňují zpracovat viditelnost jednotlivých vlastností a metod.
Balíky Balíčky v jazyce ActionScript 3.0 jsou implementovány s jmennými prostory, ale nejsou jejich synonymem. Když deklarujete balíček, implicitně vytváříte speciální typ jmenného prostoru, který je zaručeně znám v okamžiku kompilace. Jmenné prostory, když jsou vyjádřeny explicitně, nejsou nutně známy v čase kompilace. Následující příklad používá instrukci package k vytvoření jednoduchého balíčku obsahujícího jednu třídu:
Poslední aktualizace 12.5.2011
35
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
package samples { public class SampleCode { public var sampleGreeting:String; public function sampleFunction() { trace(sampleGreeting + " from sampleFunction()"); } } }
Název třídy je v tomto příkladu SampleCode. Protože třída je uvnitř vzorového balíčku, kompilátor automaticky kvalifikuje název třídy v okamžiku kompilace do plně platného názvu: samples.SampleCode. Kompilátor také kvalifikuje názvy všech vlastností nebo metod, takže sampleGreeting a sampleFunction() se stanou samples.SampleCode.sampleGreeting a samples.SampleCode.sampleFunction(). Mnoho vývojářů, obzvláště pokud mají zkušenosti s programováním v jazyce Java, volí umístění pouze tříd na horní úrovni balíčku. Jazyk ActionScript 3.0 však podporuje nejenom třídy na horní úrovni balíčku, ale také proměnné, funkce a také příkazy. Pokročilým použitím této funkce je definování jmenného prostoru na horní úrovni balíčku tak, aby byl k dispozici všem třídám v daném balíčku. Povšimněte si však, že na horní úrovni balíčku jsou povoleny pouze dva specifikátory přístupu, public a internal. Na rozdíl od jazyka Java, ve kterém lze deklarovat vnořené třídy jako soukromé, jazyk ActionScript 3.0 nepodporuje ani vnořené, ani soukromé třídy. Mnoha jinými způsoby jsou však balíčky jazyka ActionScript 3.0 podobné balíčkům v programovacím jazyce Java. Jak jste mohli vidět na předchozím příkladu, zcela platné reference balíčku jsou vyjádřeny pomocí operátoru tečka (.), stejně jako v jazyce Java. Balíčky můžete použít k organizování kódu do intuitivní hierarchické struktury pro použití jinými programátory. To usnadňuje sdílení kódu a umožňuje vytvářet vlastní balíčky pro sdílení s ostatními a používat balíčky vytvořené jinými programátory ve vlastním kódu. Používání balíčků rovněž pomáhá zajistit, aby použité názvy identifikátorů byly unikátní a nebyly ve střetu s jinými názvy identifikátorů. Ve skutečnosti by někdo mohl říci, že se jedná o primární výhodu balíčků. Například dva programátoři, kteří chtějí navzájem sdílet svůj kód, mohou vytvořit třídu s názvem SampleCode. Bez balíčků by to vedlo ke konfliktu názvů a jediným řešením by bylo přejmenování jedné ze tříd. Díky balíčkům je však konflikt názvů snadno odstranitelný a to vložením jedné, nebo lépe obou tříd do balíčku s unikátními názvy. Můžete také zahrnout integrované tečky do názvů svých balíčků a vytvořit tak vnořené balíčky. To umožňuje vytvářet hierarchické organizování balíčků. Dobrým příkladem je balíček flash.display v jazyce ActionScript 3.0. Balíček flash.display je vnořen v balíčku flash. Většina jazyka ActionScript 3.0 je organizována v rámci balíku flash. Například balíček flash.display obsahuje seznam zobrazení API, a balíček flash.events obsahuje nový model událostí.
Vytváření balíčků Jazyk ActionScript 3.0 poskytuje významnou flexibilitu způsobu, kterým je možné organizovat balíčky, třídy a zdrojové soubory. Předchozí verze jazyka ActionScript povolovaly pouze jednu třídu na zdrojový soubor a vyžadovaly, aby název zdrojového souboru odpovídal názvu třídy. Jazyk ActionScript 3.0 umožňuje zahrnout více tříd do jednoho zdrojového souboru, avšak pouze jedna třída v každém souboru může být zpřístupněna kódu, který je pro daný soubor externí. Jinými slovy pouze jedna třída v každém souboru může být deklarována uvnitř deklarace balíčku. Musíte deklarovat všechny dodatečné třídy vně definice balíčku, což tyto třídy zneviditelní pro kód vně tohoto zdrojového souboru. Název třídy deklarované uvnitř definice balíčku musí odpovídat názvu zdrojového souboru.
Poslední aktualizace 12.5.2011
36
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
Jazyk ActionScript 3.0 také poskytuje vyšší stupeň flexibility způsobu deklarování balíčků. V předchozích verzích ActionScript balíčky představovaly pouze adresáře, ve kterých byly umístěny zdrojové soubory, a nebylo nutné deklarovat balíčky příkazem package, spíše se název balíčku zahrnul jako součást plně kvalifikovaného názvu třídy ve vaší deklaraci třídy. I když balíčky stále vyjadřují adresáře v jazyku ActionScript 3.0, mohou obsahovat více než třídy. V jazyku ActionScript 3.0 použijete příkaz package k deklarování balíčku, což znamená, že můžete také deklarovat proměnné, funkce a jmenné prostory na horní úrovni balíčku. Na horní úrovni balíčku můžete také zahrnout spustitelné příkazy. Pokud deklarujete proměnné, funkce nebo jmenné prostory na horní úrovni balíčku, jediným atributem dostupným na této úrovni je public a internal a pouze jedna deklarace na úrovni balíčku na soubor může použít atribut public, bez ohledu na to, zda je tato deklarace třídou, proměnnou, funkcí nebo jmenným prostorem. Balíčky jsou užitečné pro organizování kódu a zabránění konfliktů názvů. Nezaměňujte koncept balíčků s nesouvisejícím konceptem dědičnosti třídy. Dvě třídy spočívající ve stejném balíčku budou mít společný jmenný prostor, ale jinak spolu nemusejí být nijak spojeny. Podobně, vnořené prostory nemají žádný sémantický vztah s nadřazeným balíčkem.
Importování balíčků Pokud chcete použít třídu uvnitř balíčku, musíte importovat balíček nebo jeho specifickou třídu. To je odlišné od jazyka ActionScript 2.0, kde importování tříd bylo volitelné. Zvažte například dříve uvedený příklad třídy SampleCode. Pokud třída spočívá v balíčku pojmenovaném samples, musíte použít jeden z následujících příkladů před použitím třídy SampleCode: import samples.*;
nebo import samples.SampleCode;
Obecně příkazy import by měly být co nejspecifičtější. Pokud plánujete použít pouze třídu SampleCode z balíčku samples, měli byste importovat pouze třídu SampleCode, nikoli celý balíček, ke kterému náleží. Importování celého balíčku může vést k neočekávaným konfliktům názvů. Musíte také umístit zdrojový kód, který definuje balíček nebo třídu do classpath. Třída classpath představuje uživatelem definovaný seznam cest místních adresářů, který určuje, kde bude kompilátor vyhledávat importované balíčky a třídy. Třída classpath je někdy nazývána cesta sestavení nebo cesta zdroje. Po správném importování třídy nebo balíčku použijete buď plně kvalifikovaný název třídy (samples.SampleCode) nebo pouze název třídy samotné (SampleCode). Plně kvalifikované názvy jsou užitečné v případě, že identicky pojmenované třídy, metody nebo vlastnosti vedou k nejednoznačnému kódu, ale jejich správa může být obtížná, pokud jsou použity pro všechny identifikátory. Například použití plně kvalifikovaného názvu vede k rozvláčnému kódu, když konkretizujete instanci třídy SampleCode: var mySample:samples.SampleCode = new samples.SampleCode();
Když se zvýší úroveň třídy vnořeného balíčku, čitelnost kódu se sníží. V případě, kdy jste si jisti, že nejednoznačné identifikátory nepředstavují žádný problém, můžete kód pro čtení zjednodušit pomocí jednoduchých identifikátorů. Například konkretizace nové instance třídy SampleCode je mnohem méně rozvláčná, pokud použijete pouze identifikátor třídy: var mySample:SampleCode = new SampleCode();
Pokud se pokusíte použít názvy identifikátorů bez předchozího importování příslušného balíčku nebo třídy, nebude kompilátor schopen nalézt definice třídy. Na druhou stranu, jestliže importujete balíček nebo třídu, jakýkoliv pokus o definování názvu vedoucí ke konfliktu s importovaným názvem, vygeneruje chybu.
Poslední aktualizace 12.5.2011
37
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
Když je vytvořen balíček, výchozí specifikátor přístupu pro všechny členy daného balíčku je internal, což znamená, že standardně jsou členové balíčku viditelné pouze ostatním členům tohoto balíčku. Pokud chcete, aby třída byla dostupná kódu vně balíčku, musíte deklarovat tuto třídu jako public. Například následující balíček obsahuje dvě třídy, SampleCode a CodeFormatter: // SampleCode.as file package samples { public class SampleCode {} } // CodeFormatter.as file package samples { class CodeFormatter {} }
Třída SampleCode je viditelná vně balíčku, protože je deklarovaná jako třída public. Třída CodeFormatter je nicméně viditelná pouze v rámci samotného balíčku. Pokud se pokusíte přistupovat k třídě CodeFormatter mimo vzorový balíček, dojde k chybě, jak je vidět na následujícím příkladu: import samples.SampleCode; import samples.CodeFormatter; var mySample:SampleCode = new SampleCode(); // okay, public class var myFormatter:CodeFormatter = new CodeFormatter(); // error
Pokud chcete obě třídy zpřístupnit vně balíčku, musíte je obě deklarovat jako public. Nemůžete použít atribut public pro deklarování balíčku. Plně kvalifikované názvy jsou užitečné pro vyřešení konfliktů názvů, které mohou při použití balíčků nastat. Takový scénář může nastat, pokud importujete dva balíčky definující třídy se stejným identifikátorem. Například zvažte následující balíček, který také obsahuje třídu pojmenovanou SampleCode: package langref.samples { public class SampleCode {} }
Jestliže importujete obě třídy následujícím způsobem, dojde při použití třídy SampleCode ke konfliktu názvů: import samples.SampleCode; import langref.samples.SampleCode; var mySample:SampleCode = new SampleCode(); // name conflict
Kompilátor nemá žádnou možnost zjistit, kterou třídu SampleCode použít. Chcete-li vyřešit tento konflikt, musíte využít plně kvalifikovaného názvu každé třídy, a to následujícím způsobem: var sample1:samples.SampleCode = new samples.SampleCode(); var sample2:langref.samples.SampleCode = new langref.samples.SampleCode();
Poznámka: Programátoři se znalostí C++ často zaměňují příkaz import s příkazem #include. Instrukce #include je nutná v jazyce C++ proto, že kompilátory C++ zpracovávají postupně jeden soubor za druhým, a nevyhledávají definice třídy v dalších souborech, pokud je soubor záhlaví explicitně zahrnut. Jazyk ActionScript 3.0 mí instrukci include, ale není navržen pro importování tříd a balíčků. Chcete-li importovat třídy nebo balíčky do jazyka ActionScript 3.0, musíte použít příkaz import a vložit zdrojový soubor obsahující balíček do cesty třídy.
Poslední aktualizace 12.5.2011
38
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
Jmenné prostory Jmenné prostory umožňují ovládat viditelnost vlastností a metod, které vytvoříte. Na specifikátory řízení přístupu public, private, protected, a internal můžete nahlížet jako na vestavěné jmenné prostory. Pokud tyto předdefinované specifikátory řízení přístupu nevyhovují vašim požadavkům, můžete vytvořit vlastní jmenné prostory. Pokud jste seznámeni se jmennými prostory XML, většina těchto informací pro vás nebude nová, i když syntaxe a podrobnosti o implementování jazyka ActionScript se mírně odlišuje od těch v XML. Pokud jste nikdy dříve nepracovali s jmennými prostory, koncept samotný je přímý, ale implementace má specifickou terminologii, kterou se musíte naučit. Chcete-li porozumět funkci jmenných prostorů, je dobré znát, že název vlastnosti nebo metody vždy obsahuje dvě části: identifikátor a jmenný prostor. Identifikátor je to, co obvykle považujete za název. Například identifikátory v následující definici třídy jsou sampleGreeting a sampleFunction(): class SampleCode { var sampleGreeting:String; function sampleFunction () { trace(sampleGreeting + " from sampleFunction()"); } }
Kdykoliv definice nejsou předcházeny atributem jmenného prostoru, jejich názvy jsou kvalifikovány výchozím jmenným prostorem internal, což znamená, že jsou viditelné pouze volajícím ve stejném balíčku. Pokud je kompilátor nastaven do přísného režimu, vydá upozornění, že jmenné prostory internal platí pro jakýkoli identifikátor bez atributu jmenného prostoru. Aby byl identifikátor dostupné všude, musíte specificky uvést v předponě název identifikátoru s atributem public. V předchozím příkladu kódu obě třídy sampleGreeting a sampleFunction() mají hodnotu jmenného prostoru internal. Existují tři základní kroky, které je nutné při používání jmenných prostorů používat. Nejprve musíte definovat jmenný prostor pomocí klíčového slova namespace. Například následující kód definuje jmenný prostor version1: namespace version1;
Za druhé použijete jmenný prostor namísto specifikátoru řízení přístupu v deklaraci vlastnosti nebo metody. Následující příklad vkládá funkci pojmenovanou myFunction() do jmenného prostoru version1: version1 function myFunction() {}
Za třetí, jakmile použijete jmenný prostor, můžete na něj odkazovat instrukcí use nebo kvalifikováním názvu identifikátoru jmenným prostorem. Následující příklad odkazuje na funkci myFunction() pomocí instrukce use: use namespace version1; myFunction();
Můžete také použít kvalifikovaný název pro odkazování na funkci myFunction(), jak je vidět na následujícím příkladu: version1::myFunction();
Definování jmenných prostorů Jmenné prostory obsahují jednu hodnotu, Univerzální identifikátor zdroje (URI - Uniform Resource Identifier), která se někdy nazývá název jmenného prostoru. URI umožňuje zajistit, aby definice jmenného prostoru byla jedinečná. Vytváříte jmenný prostor deklarováním definice jmenného prostoru jedním ze dvou způsobů. Můžete buď definovat jmenný prostor s explicitní URI, jako byste definovali jmenný prostor XML, nebo můžete URI vynechat. Následující příklad ukazuje, jak lze jmenný prostor definovat pomocí URI:
Poslední aktualizace 12.5.2011
39
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
namespace flash_proxy = "http://www.adobe.com/flash/proxy";
URI slouží jako unikátní identifikační řetězec pro daný jmenný prostor. Pokud vynecháte identifikátor URI, jako v následujícím příkladu, kompilátor vytvoří na místě identifikátoru URI jedinečný vnitřní identifikační řetězec. K tomuto vnitřnímu identifikačnímu řetězci nemáte přístup. namespace flash_proxy;
Jakmile definujete jmenný prostor, s URI nebo bez, tento jmenný prostor nelze předefinovat ve stejném rozsahu. Pokus o definování jmenného prostoru, jak bylo uvedeno výše ve stejném rozsahu, vede k chybám kompilátoru. Pokud je jmenný prostor definován v balíčku nebo třídě, jmenný prostor nemůže být viditelný pro kód vně tohoto balíčku nebo třídy, pokud není použit příslušný specifikátor řízení přístupu. Například následující kód zobrazuje flash_proxy jmenný prostor definovaný v balíčku flash.utils. V následujícím příkladu chybějící specifikátor řízení přístupu znamená, že jmenný prostor flash_proxy bude viditelný pouze pro kód v balíčku flash.utils a nebude viditelný pro jakýkoli kód vně tohoto balíčku: package flash.utils { namespace flash_proxy; }
Následující kód využívá atribut public pro zviditelnění jmenného prostoru flash_proxy pro kód vně balíčku: package flash.utils { public namespace flash_proxy; }
Použití jmenných prostor Použití jmenných prostor znamená vložení definice do jmenného prostoru. Definice, které lze vložit do jmenného prostoru zahrnují funkce, proměnné a konstanty (třídu do vlastního jmenného prostoru vložit nelze). Zvažte například funkci deklarovanou pomocí jmenného prostoru řízení přístupu public. Pomocí atributu public v definici funkce vloží funkci do veřejného jmenného prostoru, což ji zpřístupní pro veškerý kód. Jakmile definujete jmenný prostor, můžete jej použít stejným způsobem, jak byste použili atribut public, a definice bude dostupná pro kód, který může odkazovat na vlastní jmenný prostor. Pokud například definujete jmenný prostor example1, můžete přidat metodu nazvanou myFunction() pomocí example1 jako atributu, jak je vidět na následujícím příkladu: namespace example1; class someClass { example1 myFunction() {} }
Deklarování metody myFunction() pomocí jmenného prostoru example1 jako atributu znamená, že metoda náleží jmennému prostoru example1. Při použití jmenného prostoru byste měli mít na paměti následující:
• Můžete použít pouze jeden jmenný prostor pro každou deklaraci. • Neexistuje žádný způsob, jak aplikovat atribut jmenného prostoru pro více než jednu definici najednou. Jinými slovy, pokud chcete použít svůj jmenný prostor na deset různých funkcí, musíte přidat jmenné prostory jako atribut k jedné z deseti definic funkcí.
• Pokud použijete pouze jmenný prostor, nemůžete také uvést specifikátor řízení přístupu, protože jmenné prostory a specifikátory řízení přístupu se vzájemně vylučují. Jinými slovy, nemůžete deklarovat funkci nebo vlastnosti jako public, private, protected nebo internal kromě použití jmenného prostoru.
Poslední aktualizace 12.5.2011
40
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
Odkazování jmenných prostory Není nutné explicitně definovat odkaz na jmenný prostor, když použijete metodu nebo vlastnost deklarovanou pomocí kteréhokoliv jmenného prostoru řízení přístupu, například public, private, protected a internal. Tak tomu je proto, že přístup k těmto speciálním jmenným prostorům je řízen kontextem. Například definice vložené do jmenného prostoru private jsou automaticky dostupné kódu ve stejné třídě. Pro vámi definované jmenné prostory nicméně taková citlivost na kontext neexistuje. Chcete-li použít metodu nebo vlastnost, kterou jste vložili do vlastního jmenného prostoru, musíte na jmenný prostor odkazovat. Jmenný prostor můžete odkazovat s použitím instrukce use namespace nebo můžete kvalifikovat název se jmenným prostorem pomocí symbolu kvalifikátoru názvu (::). Odkazování jmenného prostoru pomocí instrukce use namespace „otevře” jmenný prostor, takže jej lze použít pro všechny identifikátory, které nejsou kvalifikované. Pokud jste například definovali jmenný prostor example1, můžete přistupovat k názvům v tomto jmenném prostoru pomocí use namespace example1: use namespace example1; myFunction();
Můžete otevřít více než jeden jmenný prostor najednou. Jakmile otevřete jmenný prostor s use namespace, zůstane otevřený v celém bloku kódu, ve kterém byl otevřen. Neexistuje žádný způsob, jak explicitně jmenný prostor uzavřít. Pokud budete mít otevřený více než jeden jmenný prostor, zvyšuje se tak pravděpodobnost konfliktu názvů. Pokud dáváte přednost neotevírání jmenného prostoru, můžete se vyhnout instrukci use namespace kvalifikováním názvu metody nebo vlastnosti s jmenným prostorem a symbolem kvalifikátoru jména. Například následující kód znázorňuje, jak lze kvalifikovat název myFunction() pomocí jmenného prostoru example1: example1::myFunction();
Použití jmenného prostoru Ve třídě flash.utils.Proxy, která je součástí jazyka ActionScript 3.0, můžete nalézt reálný příklad jmenného prostoru, který je použit k zabránění konfliktům názvů. Třída Proxy, která je náhradou za Object.__resolve z jazyka ActionScript 2.0 umožňuje sledovat odkazy k nedefinovaným vlastnostem nebo metodám předtím, než se vyskytne chyba. Všechny metody třídy Proxy spočívají v jmenném prostoru flash_proxy, aby nedocházelo ke konfliktu názvů. Pro lepší porozumění použití jmenného prostoru flash_proxy je nutné porozumět použití třídy Proxy. Funkce třídy Proxy je dostupná pouze třídám které z ní pocházejí. Jinými slovy, pokud chcete používat metody třídy Proxy na objekt, musí definice třídy objektu rozšiřovat třídu Proxy. Pokud chcete například sledovat pokusy volání nedefinované metody, rozšířili byste třídu Proxy a pak potlačili metodu callProperty() třídy Proxy. Můžete si pamatovat, že implementování jmenného prostoru je obvykle proces složený ze tří kroků definování, použití a pak odkazování jmenného prostoru. Protože nikdy explicitně nevoláte metody třídy Proxy, jmenný prostor flash_proxy je pouze definován a použit, ale nikdy není referencován. ActionScript 3.0, definuje jmenný prostor flash_proxy a použije jej na třídu Proxy. Kód musí pouze aplikovat jmenný prostor flash_proxy na třídy, které rozšiřují třídu Proxy. Jmenný prostor flash_proxy je definován v balíčku flash.utils způsobem obdobný následujícímu: package flash.utils { public namespace flash_proxy; }
Jmenný prostor je aplikován na metody třídy Proxy, jak je znázorněno v následujícím výňatku z třídy Proxy:
Poslední aktualizace 12.5.2011
41
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
public class Proxy { flash_proxy function callProperty(name:*, ... rest):* flash_proxy function deleteProperty(name:*):Boolean ... }
jak ukazuje následující kód, musíte nejprve importovat třídu Proxy a pak jmenný prostor flash_proxy. Musíte pak deklarovat svou třídu tak, aby rozšiřovala třídu Proxy (v případě, že kompilujete v přísném režimu, musíte také přidat atribut dynamic). Když potlačíte metodu callProperty(), musíte použít jmenný prostor flash_proxy. package { import flash.utils.Proxy; import flash.utils.flash_proxy; dynamic class MyProxy extends Proxy { flash_proxy override function callProperty(name:*, ...rest):* { trace("method call intercepted: " + name); } } }
Pokud vytvoříte instanci třídy MyProxy a zavoláte nedefinovanou metodu, například metodu testing() volanou v následujícím příkladu, objekt Proxy sleduje volání metody a vykonává příkazy uvnitř potlačené metody callProperty() (v tomto případě jednoduchý příkaz trace()). var mySample:MyProxy = new MyProxy(); mySample.testing(); // method call intercepted: testing
Existují dvě výhody, proč mít metody třídy Proxy uvnitř jmenného prostoru flash_proxy. První, mít samostatné jmenné prostory redukuje nepořádek ve veřejném rozhraní jakékoliv třídy, která rozšiřuje třídu Proxy. (Existuje asi tucet metod v třídě Proxy, které můžete potlačit, všechny nejsou navrženy pro přímé volání. Jejich umístění do veřejného jmenného prostoru může být matoucí.) Druhá, použití jmenného prostoru flash_proxy zabraňuje konfliktu názvů v případě, že vaše podtřída Proxy obsahuje metody instance s názvy odpovídajícími metodám třídy Proxy. Můžete například chtít pojmenovat jednu z vlastních metod callProperty(). Následující kód je přijatelný, protože vaše verze metody callProperty() je v jiném jmenném prostoru. dynamic class MyProxy extends Proxy { public function callProperty() {} flash_proxy override function callProperty(name:*, ...rest):* { trace("method call intercepted: " + name); } }
Jmenné prostory mohou být také užitečné v případě, že chcete zajistit přístup k metodám nebo vlastnostem způsobem, který nelze uskutečnit se čtyřmi specifikátory řízení přístupu (public, private, internal a protected). Například můžete mít několik pomocných meto, které jsou rozprostřeny v několika balíčcích. Chcete například všechny tyto metody zpřístupnit všem svým balíčkům, ale nechcete je mít veřejně přístupné. To uskutečníte tak, že vytvoříte jmenný prostor a použijete jej jako vlastní speciální specifikátor řízení přístupu.
Poslední aktualizace 12.5.2011
42
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
Následující příklad ilustruje použití uživatelem definovaného jmenného prostoru k seskupení dvou funkcí, jež spočívají v různých balíčcích. Jejich seskupením do stejného jmenného prostoru můžete obě funkce zviditelnit ve třídě nebo balíčku pomocí jediného příkazu use namespace. Tento příklad používá čtyři soubory k demonstrování této techniky. Všechny soubory musí být v cestě pro třídu. První soubor, myInternal.as, se použije pro definování jmenného prostoru myInternal. Protože soubor je v balíčku pojmenovaném podle příkladu, musíte umístit soubor do složky pojmenované podle příkladu. Jmenný prostor je označen jako public, takže jej lze importovat do ostatních balíčků. // myInternal.as in folder example package example { public namespace myInternal = "http://www.adobe.com/2006/actionscript/examples"; }
Druhý a třetí soubor, Utility.as a Helper.as, definují třídy obsahující metody, které by měly být dostupné pro ostatní balíčky. Třída Utility je v balíčku example.alpha, což znamená, že soubor by měl být umístěn dovnitř složky pojmenované alpha, která je podsložkou složky v příkladu. Třída Helper je v balíčku example.beta, což znamená, že soubor by měl být umístěn dovnitř složky pojmenované beta, která je podsložkou složky v příkladu. Oba tyto balíčky, example.alpha i example.beta, musí importovat jmenný prostor před jeho použitím. // Utility.as in the example/alpha folder package example.alpha { import example.myInternal; public class Utility { private static var _taskCounter:int = 0; public static function someTask() { _taskCounter++; } myInternal static function get taskCounter():int { return _taskCounter; } } }
Poslední aktualizace 12.5.2011
43
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
// Helper.as in the example/beta folder package example.beta { import example.myInternal; public class Helper { private static var _timeStamp:Date; public static function someTask() { _timeStamp = new Date(); } myInternal static function get lastCalled():Date { return _timeStamp; } } }
Čtvrtý soubor, NamespaceUseCase.as, je hlavní třídou aplikaci a měl by být příbuzným složky příkladu. V aplikaci Flash Professional tato třída bude použita jako třída dokumentu pro FLA. Třída NamespaceUseCase rovněž importuje jmenný prostor myInternal a používá jej pro zavolání statických metod, které spočívají v jiných balíčcích. Příklad používá statické metody pouze pro zjednodušení kódu. Statické a instanční metody mohou být vloženy do jmenného prostoru myInternal. // NamespaceUseCase.as package { import flash.display.MovieClip; import example.myInternal; // import namespace import example.alpha.Utility;// import Utility class import example.beta.Helper;// import Helper class public class NamespaceUseCase extends MovieClip { public function NamespaceUseCase() { use namespace myInternal; Utility.someTask(); Utility.someTask(); trace(Utility.taskCounter); // 2 Helper.someTask(); trace(Helper.lastCalled); // [time someTask() was last called] } } }
Poslední aktualizace 12.5.2011
44
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
Proměnné Proměnné umožňují uložit hodnoty, které v programu používáte. Pro deklarování proměnné musíte použít příkaz var s názvem proměnné. V jazyce ActionScript 3.0 je použití příkazu var vyžadováno vždy. Například následující řádek jazyka ActionScript deklaruje proměnnou pojmenovanou i: var i;
Pokud při deklarování proměnné vynecháte příkaz var, zobrazí se v přísném režimu chyba kompilátoru a ve standardním režimu chyba spuštění. Následující řádek kódu například způsobí chybu v případě, že proměnná i nebyla dříve definována: i; // error if i was not previously defined
Pro spojení proměnné s datovým typem musíte toto učinit, když deklarujete proměnnou. Deklarování proměnné bez označení jejího typu je povoleno, ale v přísném režimu vyvolá výstrahu kompilátoru. Typ proměnné definujete připojením dvojtečky (:) za název a typem proměnné. Například následující kód deklarujete proměnnou i typu int: var i:int;
Můžete přiřadit hodnotu proměnné pomocí operátoru (=). Například následující kód deklarujete proměnnou i a přiřazuje jí hodnotu 20: var i:int; i = 20;
Patrně bude pohodlnější přiřadit hodnotu proměnné ve stejný okamžik, když deklarujete proměnnou, jako v následujícím příkladu: var i:int = 20;
Technika přiřazování hodnoty proměnné v době její deklarace je běžně použita nejenom pro přiřazování primitivních hodnot, jako jsou celočíselné hodnoty a řetězce, ale také při vytváření pole nebo konkretizaci instance třídy. Následující příklad zobrazuje pole, které má deklarovanou a přiřazenou hodnotu pomocí jedné řádky kódu. var numArray:Array = ["zero", "one", "two"];
Můžete vytvořit instanci třídy pomocí operátoru new. Následující příklad vytváří instanci pojmenovanou CustomClass a přiřazuje referenci nově vytvořené instanci třídy proměnné pojmenované customItem: var customItem:CustomClass = new CustomClass();
Pokud máte pro deklarován více než jednu proměnnou, můžete deklarovat všechny v jedné řádce pomocí operátoru čárka (,) a proměnné tak oddělit. Například následující kód deklarujete tři proměnné v jedné řádce kódu: var a:int, b:int, c:int;
Můžete také přiřadit hodnoty každé proměnné ve stejné řádce kódu. Například následující kód deklaruje tři proměnné (a, b a c) a přiřazuje každé hodnotu: var a:int = 10, b:int = 20, c:int = 30;
I když můžete použít operátor čárka pro seskupení deklarace proměnných do jednoho příkazu, může to snížit čitelnost kódu.
Poslední aktualizace 12.5.2011
45
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
Porozumění rozsahu proměnných Rozsah proměnné představuje oblast kódu, kde může být proměnná zpřístupněna lexikálním odkazem. Globální proměnná je taková, která je definovaná ve všech oblastech kódu, zatímco lokální proměnná je taková, která je definována pouze v jedné části kódu. V jazyce ActionScript 3.0 mají proměnné vždy přiřazen rozsah funkce nebo třídy, ve které jsou deklarované. Globální proměnná je taková, kterou definujete vně funkce nebo definice třídy. Například následující kód vytváří globální proměnnou strGlobal jejím deklarováním vně veškerých funkcí. Příklad ukazuje, že globální proměnná je k dispozici uvnitř a vně definice funkce. var strGlobal:String = "Global"; function scopeTest() { trace(strGlobal); // Global } scopeTest(); trace(strGlobal); // Global
Místní proměnou deklarujete pomocí proměnné uvnitř definice funkce. Nejmenší oblast kódu, pro kterou lze definovat místní proměnnou, je definice funkce. Místní proměnná deklarovaná v rámci funkce existuje pouze v této funkci. Pokud například deklarujete proměnnou s názvem str2 v rámci funkce nazvané localScope(), tato proměnná nebude vně funkce dostupná. function localScope() { var strLocal:String = "local"; } localScope(); trace(strLocal); // error because strLocal is not defined globally
Pokud název proměnné použité jako místní proměnná bude již deklarován jako globální proměnná, místní definice skryje (nebo vytvoří stín) globální definici, když bude místní proměnná v jejím rozsahu. Globální proměnná se stále vyskytuje vně funkce. Například následující kód vytváří globální řetězcovou proměnnou pojmenovanou str1 a pak vytváří místní proměnou stejného názvu uvnitř funkce scopeTest(). Příkaz trace uvnitř funkce odesílá na výstup místní hodnotu proměnné, ale příkaz trace vně funkce odesílá na výstup globální hodnotu proměnné. var str1:String = "Global"; function scopeTest () { var str1:String = "Local"; trace(str1); // Local } scopeTest(); trace(str1); // Global
Proměnné jazyka ActionScript, na rozdíl od proměnných v C++ a Java, nemají rozsah blok-úroveň. Blok kódu je libovolná skupina příkazů mezi levou složenou závorkou ( { ) a pravou složenou závorkou ( } ). V některých programovacích jazycích, například C++ a Java, proměnné deklarované uvnitř bloku kódu nejsou dostupné vně tohoto bloku. Toto omezení je nazváno rozsah blok-úroveň a v jazyce ActionScript neexistuje. Pokud deklarujete proměnnou uvnitř bloku kódu, tato proměnná nebude dostupná pouze v tomto bloku kódu, ale také v ostatních částech funkce, ke které blok kódu náleží. Například následující funkce obsahuje proměnné, které jsou definované v různých rozsazích bloku. Všechny proměnné jsou dostupné prostřednictvím funkce.
Poslední aktualizace 12.5.2011
46
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
function blockTest (testArray:Array) { var numElements:int = testArray.length; if (numElements > 0) { var elemStr:String = "Element #"; for (var i:int = 0; i < numElements; i++) { var valueStr:String = i + ": " + testArray[i]; trace(elemStr + valueStr); } trace(elemStr, valueStr, i); // all still defined } trace(elemStr, valueStr, i); // all defined if numElements > 0 } blockTest(["Earth", "Moon", "Sun"]);
Zajímavým dopadem neexistence rozsahu blok-úroveň je to, že můžete číst proměnnou nebo do ní zapisovat předtím, než je deklarovaná, pokud je deklarovaný před ukončením funkce. Tak tomu je díky technice nazvané zvedání, což znamená, že kompilátor přesouvá všechny deklarace proměnných na horní stranu funkce. Například následující kód je zkompilován i v případě, že se počáteční funkce trace() pro proměnnou num vyskytuje před deklarováním proměnné num: trace(num); // NaN var num:Number = 10; trace(num); // 10
Kompilátor však „nezvedne“ žádné příkazy přiřazení. To vysvětluje, proč počáteční trace() proměnné num vede k NaN (není číslo), což je výchozí hodnota proměnných datového typu Number. To znamená, že můžete přiřadit hodnoty proměnným ještě před jejich deklarováním, jak je vidět v následujícím příkladu: num = 5; trace(num); // 5 var num:Number = 10; trace(num); // 10
Výchozí hodnoty Výchozí hodnota je hodnota, kterou proměnná obsahuje před nastavením její hodnoty. Proměnnou inicializujete, když poprvé nastavíte její hodnotu. Pokud deklarujete proměnou, ale nenastavíte její hodnotu, tato proměnná bude neinicializovaná. Hodnota neinicializované proměnné závisí na datovém typu. Následující tabulka popisuje výchozí hodnoty proměnných organizované podle datového typu: Typ dat
Výchozí hodnota
Booleovské
false
int
0
Number
NaN
Objekt
null
Řetězec
null
Poslední aktualizace 12.5.2011
47
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
Typ dat
Výchozí hodnota
uint
0
Není deklarováno (ekvivalent anotaci typu *)
undefined
Všechny ostatní třídy, včetně uživatelem definovaných tříd.
null
Pro proměnné typu Number je výchozí hodnota NaN (není číslo), což je speciální hodnota definovaná standardem IEEE-754 pro vyjádření hodnoty, která nepředstavuje číslo. Pokud deklarujete proměnnou, ale nikoliv její datový typ, bude platit výchozí datový typ *, což ve skutečnosti znamená, že proměnná bude bez typu. Pokud také neinicializujete proměnnou bez typu pomocí hodnoty, její výchozí hodnota je undefined. Pro datové typy jiné, než Boolean, Number, int a uint je výchozí hodnota kterékoliv proměnné null. To platí pro všechny třídy definované jazykem ActionScript 3.0, stejně jako pro všechny vlastní třídy, které vytvoříte. Hodnota null není platnou hodnotou pro proměnné typu Boolean, Number, int nebo uint. Pokud se pokusíte přiřadit hodnotu null takové proměnné, hodnota je převedena na výchozí hodnotu pro daný datový typ. Pro proměnné typu Object můžete přiřadit hodnotu null. Pokud se pokusíte přiřadit hodnotu undefined proměnné typu Object, hodnota je převedena na null. Pro proměnné typu Number existuje speciální funkce horní úrovně pojmenovaná isNaN(), která vrací booleovskou hodnotu true v případě, že proměnná není číslem, jinak vrací hodnotu false.
Typy dat Datový typ definuje soubor hodnot. Například datový typ booleovská hodnota je souborem přesně dvou hodnot: true a false. Kromě datového typu booleovská hodnota jazyk ActionScript 3.0 definuje několik běžně používaných datových typů, například String, Number a Array. Můžete definovat vlastní datové typy pomocí tříd nebo rozhraní a definovat tak vlastní soubor hodnot. Všechny hodnoty v jazyce ActionScript 3.0, ať už primitivní nebo komplexní, jsou objekty. Primitivní hodnota je hodnota náležející jednomu z následujících datových typů: booleovský, int, Number, String a uint. Práce s primitivními hodnotami je obvykle rychlejší než s komplexními hodnotami, protože jazyk ActionScript ukládá primitivní hodnoty speciálním způsobem, které umožňuje optimalizaci paměti a rychlosti. Poznámka: Pro čtenáře se zájmem o technické podrobnosti jazyk ActionScript ukládá primitivní hodnoty interně jako nezměnitelné objekty. Ve skutečnosti to, že jsou uloženy jako nezměnitelné objekty znamená, že předání odkazem je efektivně shodné jako předání hodnotou. To snižuje využití paměti a zvyšuje rychlost vykonávání, protože odkazy jsou obvykle výrazně menší než hodnoty samotné. Komplexní hodnota je hodnota, která není primitivní. Datové typy definující komplexní hodnoty zahrnují: Array, Date, Error, Function, RegExp, XML a XMLList. Mnoho programovacích jazyků odlišuje mezi primitivními hodnotami a jejich objekty obalu. Například jazyk Java má primitivní hodnotu int a třídu java.lang.Integer, která jí obaluje. Primitivní hodnoty Java nejsou objekty, ale jejich obaly ano, což činí primitivní hodnoty užitečné pro jedny operace a objekty obalu vhodnější pro jiné operace. V jazyku ActionScript 3.0 primitivní hodnoty a jejich objekty obalu jsou z praktických účelů nerozlišitelné. Všechny hodnoty, i primitivní hodnoty, jsou objekty. Běhový modul pracuje s těmito primitivními typy jako se speciálními případy, které se chovají jako objekty, ale nevyžadují normální doplňky související s vytvářením objektů. To znamená, že následující dva řádky kódu jsou shodné:
Poslední aktualizace 12.5.2011
48
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
var someInt:int = 3; var someInt:int = new int(3);
Všechny primitivní a komplexní datové typy uvedené výše jsou definovány třídami jádra jazyka ActionScript 3.0. Třídy jádra umožňují vytvářet objekty pomocí liberálových hodnot namísto pomocí operátoru new. Například můžete vytvořit pole pomocí literálové hodnoty nebo konstruktoru třídy Array, a to takto: var someArray:Array = [1, 2, 3]; // literal value var someArray:Array = new Array(1,2,3); // Array constructor
Kontrola typu Kontrola typu může nastat buď v čase kompilace nebo v čase spuštění. Staticky zadávané jazyky, například C++ a Java, provádějí kontrolu typu v okamžiku kompilace. Dynamicky zadávané jazyky, například Smalltalk a Python, provádějí kontrolu typu v okamžiku spuštění. Jako dynamicky zadávaný má jazyk ActionScript 3.0 kontrolu typu během spouštění, ale podporuje také kontrolu během kompilace díky speciálnímu režimu kompilátoru, nazvanému přísný režim. V přísném režimu kontrola typu nastává v čase kompilace i spuštění, ale ve standardním režimu pouze v čase spuštění. Dynamicky zadávané jazyky nabízejí vynikající flexibilitu když svůj kód strukturujete, ale za cenu toho, že se chyby typu projeví až v době spuštění. Staticky zadávané jazyky hlásí chyby typu v době kompilace, ale za cenu toho, že vyžaduje známost informace typu v čase kompilace.
Kontrola typu v čase kompilace Kontrola typu v čase kompilace je často vhodnější u větších projektů, protože s rostoucí velikostí projektu se obvykle důležitost flexibility datového typu snižuje, na rozdíl od odstranění chyb typu, která je nutná co nejdříve. Proto je kompilátor jazyka ActionScript v aplikacích Flash Professional a Flash Builder standardně nastaven na spouštění v přísném režimu. Adobe Flash Builder Přísný režim lze v aplikaci Flash Builder vypnout pomocí nastavení kompilátoru jazyka ActionScript v dialogovém okně Vlastnosti projektu.
K zajištění kontroly typu v čase kompilace je nutné, aby kompilátor znal informace o datovém typu pro proměnné nebo výrazy použité v kódu. Chcete-li explicitně deklarovat datový typ pro proměnnou, přidejte operátor dvojtečku (:) následovanou datovým typem jako příponou názvu proměnné. Chcete-li připojit k datovému typu parametr, použijte operátor dvojtečku následovanou datovým typem. Například následující kód přidává informaci o datovém typu k parametru xParam a deklaruje proměnnou myParam s explicitním datovým typem: function runtimeTest(xParam:String) { trace(xParam); } var myParam:String = "hello"; runtimeTest(myParam);
V přísném režimu kompilátor jazyka ActionScript hlásí neshody typu jako chyby kompilátoru. Například následující kód deklaruje parametr funkce xParam typu Object, ale později se pokusí přiřadit hodnoty typu String a Number tomuto parametru. To v přísném režimu vede k chybě kompilátoru.
Poslední aktualizace 12.5.2011
49
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
function dynamicTest(xParam:Object) { if (xParam is String) { var myStr:String = xParam; // compiler error in strict mode trace("String: " + myStr); } else if (xParam is Number) { var myNum:Number = xParam; // compiler error in strict mode trace("Number: " + myNum); } }
I v přísném režimu se můžete selektivně rozhodnout pro kontrolu v čase kompilace a to ponecháním pravé straně přiřazovacího příkazu nezadané. Můžete označit proměnnou nebo výraz jako bez typu buď vynecháním anotace typu nebo pomocí speciální anotace typu hvězdičky (*). Bude-li například parametr xParam v předchozím příkladu modifikován tak, aby již neměl anotaci typu, bude kód zkompilován v přísném režimu: function dynamicTest(xParam) { if (xParam is String) { var myStr:String = xParam; trace("String: " + myStr); } else if (xParam is Number) { var myNum:Number = xParam; trace("Number: " + myNum); } } dynamicTest(100) dynamicTest("one hundred");
Kontrola typu v době spuštění Kontrola typu v době spuštění nastává v jazyce ActionScript 3.0 bez ohledu na to, zda kompilaci provádíte v přísném nebo standardním režimu. Zvažte situaci, ve které je hodnota 3 předána jako argument funkci, která očekává pole. V přísném režimu kompilátor vygeneruje chybu, protože hodnota 3 není kompatibilní s datovým typem Array. Pokud přísný režim vypnete a spustíte standardní režim, nebude kompilátor neshodu typu signalizovat, ale kontrola typu za běhu povede k vyvolání chyby v čase zpracování. Následující příklad zobrazuje funkci pojmenovanou typeTest(), která očekává argument Array, avšak předána je hodnota 3. To způsobí chybu v okamžiku spuštění ve standardním režimu, protože hodnota 3 není členem datového typu (Array) deklarovaných pro parametr. function typeTest(xParam:Array) { trace(xParam); } var myNum:Number = 3; typeTest(myNum); // run-time error in ActionScript 3.0 standard mode
Poslední aktualizace 12.5.2011
50
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
Mohou také nastat situace, kde se zobrazí chyba dat při spuštění, i když pracujete v přísném režimu. To je možné v případě použití přísného režimu, ale rozhodnete se nepoužívat kontrolu v okamžiku kompilace pomocí proměnné bez stanoveného typu. Když použijete proměnnou bez stanoveného typu, neeliminujete kontrolu typu, ale spíše ji odkládejte na dobu spuštění. Pokud například proměnná myNum v předchozím příkladu nemá deklarovaný datový typ, nemůže kompilátor detekovat neshodu typu, ale kód vygeneruje chybu v čase zpracování, protože porovná hodnotu za běhu parametru myNum, který je v důsledku příkazu přiřazení nastaven na hodnotu 3, s typem parametru xParam, který je nastaven na datový typ Array. function typeTest(xParam:Array) { trace(xParam); } var myNum = 3; typeTest(myNum); // run-time error in ActionScript 3.0
Kontrola typu v době spuštění rovněž umožňuje flexibilnější použití dědičnosti, než kontrola v době kompilace. Odložením kontroly typu na dobu spuštění ve standardním režimu umožňuje odkazovat vlastnosti podtřídy i v případě povýšení. Povýšení nastává v případě, že použijete základní třídu k deklarování typu instance třídy, ale ke konkretizaci použijete podtřídu. Můžete například vytvořit třídu pojmenovanou ClassBase, která může být rozšířena (třídy s atributem final nemohou být rozšířeny): class ClassBase { }
Poté vytvoříte podtřídu pro ClassBase pojmenovanou ClassExtender, která má jednu vlastnost pojmenovanou someString, a to takto: class ClassExtender extends ClassBase { var someString:String; }
Pomocí obou tříd můžete vytvořit instanci třídy, která je deklarovaná pomocí datového typu ClassBase, ale konkretizována je pomocí konstruktoru ClassExtender. Povýšení je považováno za bezpečnou operaci, protože základní třída neobsahuje žádné vlastnosti nebo metody, které nejsou v podtřídě. var myClass:ClassBase = new ClassExtender();
Podtřída však neobsahuje vlastnosti nebo metody, které nemá základní třída. Například třída ClassExtender obsahuje vlastnost someString, která ve třídě ClassBase neexistuje. V jazyce ActionScript 3.0 ve standardním režimu můžete odkazovat tuto vlastnost pomocí instance myClass bez generování chyby v době kompilace, jak je vidět na následujícím příkladu: var myClass:ClassBase = new ClassExtender(); myClass.someString = "hello"; // no error in ActionScript 3.0 standard mode
Operátor is Pomocí operátoru is lze testovat, zda je proměnná nebo výraz členem daného datového typu. V předchozí verzi jazyka ActionScript operátor instanceof zajišťovat tutéž funkci, ale v ActionScript 3.0 operátor instanceof by neměl být k testování členství v datovém typu používán. Operátor is by měl být použit namísto operátoru instanceof pro ruční kontrolu typu, protože výraz x instanceof y pouze kontroluje prototypový řetězec x, zda-li existuje y (a v ActionScript 3.0 prototypový řetězec neposkytuje kompletní obraz o hierarchii dědičnosti).
Poslední aktualizace 12.5.2011
51
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
Operátor is prověřuje správnou hierarchii dědičnosti a lze jej použít ke kontrole nejenom zda je objekt instancí specifické třídy, ale také ke kontrole, zda je objekt instancí třídy, která implementuje specifické rozhraní. Následující příklad vytváří instanci třídy Sprite pojmenovanou mySprite a používá operátor is k testování, zda je mySprite instancí tříd Sprite a DisplayObject a zda implementuje rozhraní IEventDispatcher: var mySprite:Sprite = new Sprite(); trace(mySprite is Sprite); // true trace(mySprite is DisplayObject);// true trace(mySprite is IEventDispatcher); // true
Operátor is kontroluje hierarchii dědičnosti a správně hlásí, že mySprite je kompatibilní s třídami Sprite a DisplayObject (třída Sprite je podtřídou třídy DisplayObject). Operátor is rovněž kontroluje, zda je mySprite odvozená z některých tříd, které implementují rozhraní IEventDispatcher. Protože třída Sprite je odvozená z třídy EventDispatcher, která implementuje rozhraní IEventDispatcher, operátor is správně hlásí, že mySprite implementuje stejné rozhraní. Následující příklad zobrazuje stejné testy z předchozího příkladu, avšak s operátorem instanceof namísto is. Operátor instanceof správně identifikuje, že mySprite je instancí Sprite nebo DisplayObject, ale vrací false, když je použit pro testování, zda mySprite implementuje rozhraní IEventDispatcher. trace(mySprite instanceof Sprite); // true trace(mySprite instanceof DisplayObject);// true trace(mySprite instanceof IEventDispatcher); // false
Operátor as Pomocí operátoru as lze rovněž kontrolovat, zda je výraz členem daného datového typu. Na rozdíl od operátoru is nevrací operátor as booleovskou hodnotu. Místo toho operátor as vrací hodnotu výrazu, namísto true a hodnotu null namísto false. Následující příklad ukazuje výsledky použití operátoru as místo operátoru is v jednoduchém případě kontroly, zda je instance Sprite členem datových typů DisplayObject, IEventDispatcher a Number. var mySprite:Sprite = new Sprite(); trace(mySprite as Sprite); // [object Sprite] trace(mySprite as DisplayObject); // [object Sprite] trace(mySprite as IEventDispatcher); // [object Sprite] trace(mySprite as Number); // null
Když použijete operátor as, operand na pravé straně musí být datovým typem. Pokus použít výraz jiný, než datový typ na pravé straně povede k chybě.
Dynamické třídy Dynamické třídy definují objekt, který může být změně v době spuštění přidáním nebo změnou vlastností a metod. Třída, která není dynamická, například String, je zapouzdřenou třídou. Nemůžete přidávat vlastnosti nebo metody do zapouzdřené třídy v době spuštění. Dynamické třídy vytváříte pomocí atributu dynamic při deklarování třídy. Například následující kód vytváří dynamickou třídu pojmenovanou Protean:
Poslední aktualizace 12.5.2011
52
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
dynamic class Protean { private var privateGreeting:String = "hi"; public var publicGreeting:String = "hello"; function Protean() { trace("Protean instance created"); } }
Jestliže později vytvoříte instanci třídy Protean, můžete k ní přidávat vlastnosti nebo metody vně definice třídy. Například následující kód vytváří instanci třídy Protean a přidává vlastnost pojmenovanou aString a vlastnost pojmenovanou aNumber do instance: var myProtean:Protean = new Protean(); myProtean.aString = "testing"; myProtean.aNumber = 3; trace(myProtean.aString, myProtean.aNumber); // testing 3
Vlastnosti přidané do instance dynamické třídy jsou entity spuštění, takže jakákoliv kontrola typu je prováděna v době spuštění. Nemůžete přidat anotaci typu k vlastnosti, kterou přidáváte tímto způsobem. Můžete také přidat metodu instanci myProtean definování funkce a připojením funkce k vlastnosti instance myProtean. Následující kód přesouvá příkaz trace do metody pojmenované traceProtean(): var myProtean:Protean = new Protean(); myProtean.aString = "testing"; myProtean.aNumber = 3; myProtean.traceProtean = function () { trace(this.aString, this.aNumber); }; myProtean.traceProtean(); // testing 3
Metody takto vytvořené nemají přístup k žádným soukromým vlastnostem nebo metodám třídy Protean. Kromě toho, i reference na veřejné vlastnosti nebo metody třídy Protean musí být kvalifikovaná buď klíčový slovem this nebo názvem třídy. Následující příklad ukazuje metodu traceProtean() pokoušející se o přístup k soukromé a veřejné proměnné třídy Protean. myProtean.traceProtean = function () { trace(myProtean.privateGreeting); // undefined trace(myProtean.publicGreeting); // hello }; myProtean.traceProtean();
Popisy typů dat Primitivní datové typy zahrnují Boolean, int, Null, Number, String, uint a void. Třídy jádra ActionScript rovněž definují následující komplexní datové typy: Object, Array, Date, Error, Function, RegExp, XML a XMLList.
Datový typ Boolean Datový typ Boolean zahrnuje dvě hodnoty: true (pravda) a false (nepravda). Pro booleovskou hodnotu nejsou platné žádné jiné hodnoty. Výchozí hodnota booleovské proměnné, která byla deklarovaná, avšak neinicializována, je false.
Poslední aktualizace 12.5.2011
53
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
Datový typ int Datový typ int je uložen interně jako 32bitová celočíselná hodnota a zahrnuje soubor celých čísel od -2 147 483 648 (-231) do 2 147 483 647 (231 - 1) včetně. Předchozí verze jazyka ActionScript nabízely pouze datový typ Number, který byl používán pro celočíselné hodnoty a hodnoty s desetinnou čárkou. V jazyce ActionScript 3.0 nyní máte přístup k nízko úrovňovým typům pro 32bitové celočíselné hodnoty se znaménkem nebo bez něj. Pokud proměnná nepotřebuje čísla s plovoucí čárkou, použití datového typu int místo datového typu Number by mělo být rychlejší a účinnější. Pro celočíselné hodnoty mimo rozsah minimální a maximální hodnoty int použijte datový typ Number, který dokáže pracovat s hodnotami mezi kladnou a zápornou hodnotu 9 007 199 254 740 992 (53bitová celočíselná hodnota). Výchozí hodnota pro proměnné, které jsou typu int, je 0.
Datový typ null Datový typ null obsahuje pouze jednu hodnotu, null. Toto je výchozí hodnota pro datový typ String a všechny třídy, které definují komplexní datové typy, včetně třídy Object. Žádný jiný primitivní datový typ, například Boolean, Number, int a uint, hodnotu null neobsahuje. Pokud se za běhu pokusíte přiřadit hodnotu null k proměnné typu Boolean, Number, int nebo uint, bude hodnota null převedena na odpovídající výchozí hodnotu. Nemůžete použít tento datový typ jako anotaci typu.
Datový typ Number V jazyce ActionScript 3.0 datový typ Number může zastupovat celočíselné hodnoty, celočíselné hodnoty bez znaménka a desetinná čísla. Pro maximalizaci výkonu byste měli používat datový typ Number pouze pro celočíselné hodnoty vyšší, než mohou uložit 32bitové typy int a uint nebo pro desetinná čísla. Chcete-li uložit desetinné číslo, uveďte v čísle desetinnou čárku. Jestliže desetinnou čárku vynecháte, bude číslo uloženo jako celočíselná hodnota. Datový typ Number využívá 64bitový formát s dvojitou přesností, jak je specifikováno standardem IEEE pro binární aritmetiku s plovoucí desetinou čárkou (IEEE-754). Tento standard určuje, jak mají být desetinná čísla uložena pomocí 64 dostupných bitů. Jeden bit se používá k označení, zda je číslo kladné nebo záporné. Jedenáct bitů se používá pro exponent, který je uložen jako základ 2. Zbývajících 52 bitů se používá pro uložení mantisy (také significand), což je číslo umocněné exponentem. Použitím některých bitů k uložení exponentu může datový typ Number uložit desetinná čísla významně větší, než pokud by byly všechny bity použity pro mantisu. Pokud například datový typ Number používá všech 64 bitů k uložení mantisy, může uložit číslo až o hodnotě 265 - 1. Použitím 11 bitů k uložení exponentu může datový typ Number zvýšit svou mantisu na mocninu 21023. Maximální a minimální hodnoty, které může typ Number vyjadřovat, jsou uloženy ve statických vlastnostech třídy Number nazvaných Number.MAX_VALUE a Number.MIN_VALUE. Number.MAX_VALUE == 1.79769313486231e+308 Number.MIN_VALUE == 4.940656458412467e-324
I když tento rozsah čísel je enormní, cenou za tento rozsah je přesnost. Datový typ Number používá 52 bitů k uložení mantisy s tím výsledkem, že čísla vyžadující k přesnému vyjádření více než 52 bitů, například zlomek 1/3, jsou pouze přibližné aproximace. Pokud aplikace vyžaduje absolutní přesnost s desetinnými čísly, musíte použít software implementující aritmetiku s desetinnými čísly v desítkové soustavě, jako protiklad aritmetiky desetinných čísel v soustavě binární. Když uložíte celočíselné hodnoty jako datový typ Number, použije se pouze 52 bitů mantisy. Datový typ Number použije těchto 52 bitů a speciální skrytý bit k vyjádření celočíselné hodnoty od 9 007 199 254 740 992 (-253) do 9 007 199 254 740 992 (253).
Poslední aktualizace 12.5.2011
54
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
Hodnota NaN slouží nejen jako výchozí hodnota pro proměnné typu Number, ale také jako výsledek každé operace, která by měla vrátit číslo, ale nečiní tak. Pokud se například pokusíte vypočítat druhou odmocninu záporného čísla, bude výsledkem hodnota NaN. Jiné speciální hodnoty Number zahrnují kladné nekonečno a záporné nekonečno. Poznámka: Výsledkem dělení 0 je pouze NaN v případě, že dělitel je také 0. Dělení 0 dává ve výsledku infinity, pokud je dělenec kladný, nebo -infinity, pokud je dělenec záporný.
Datový typ String Datový typ String představuje posloupnost 16bitových znaků. Data String jsou uložena interně jako znaky Unicode, pomocí formátu UTF-16. Data String jsou nezměnitelné hodnoty, stejně jako v programovacím jazyce Java. Operace s hodnotou String vrací novou instanci řetězce. Výchozí hodnota proměnné deklarované datovým typem String je null. Hodnota null není stejná jako prázdný řetězec („"). Hodnota null znamená, že proměnná v sobě nemá uloženou žádnou hodnotu, zatímco prázdný řetězec značí, že proměnná má hodnotu, kterou je řetězec neobsahující žádné znaky.
Datový typ uint Datový typ uint je uložen interně jako 32bitová celočíselná hodnota bez znaménka a zahrnuje soubor celých čísel od 0 do 4 294 967 295 (232 - 1) včetně. Datový typ uint použijte pro zvláštní okolnosti, které volají po nezáporných celočíselných hodnotách. Datový typ uint musíte například použít k vyjádření hodnot obrazového bodu, protože datový typ unit má vnitřní bit pro znaménko a nehodí se pro manipulaci s hodnotami barev. Pro celočíselné hodnoty větší než maximální hodnota uint použijte datový typ Number, který dokáže pracovat až s 53bitovými celočíselnými hodnotami. Výchozí hodnota pro proměnné, které jsou typu uint je 0.
Datový typ void Datový typ void obsahuje pouze jednu hodnotu, undefined. V předchozích verzích jazyka ActionScript byla hodnota undefined výchozí pro instance třídy Object. V jazyce ActionScript 3.0 je výchozí hodnota pro instance Object null. Pokud se pokusíte přiřadit hodnotu undefined instanci třídy Object, bude tato hodnota převedena na hodnotu null. Hodnotu undefined můžete přiřadit pouze k proměnným, které nemají stanoven typ. Proměnné bez typu jsou ty, které nemají anotaci typu, nebo používají symbol hvězdičky (*) jako anotaci typu. Můžete použít void pouze jako anotaci vráceného typu.
Datový typ Object Datový typ Object je definován třídou Object. Třída Objekt slouží jako základní třída pro všechny definice tříd v jazyce ActionScript. Datový typ Object ve verzi ActionScript 3.0 se odlišuje od předchozích verzí třemi způsoby. První, datový typ Object již není výchozím pro proměnné bez anotace typu. Druhý, datový typ Object již nezahrnuje hodnotu undefined, která byla výchozí hodnotou pro instance Object. Třetí, v jazyce ActionScript 3.0 je výchozí hodnota instance třídy Object null. V předchozích verzích jazyka ActionScript byla proměnná bez anotace typu automaticky definována jako datový typ Object. Tak tomu již v jazyce ActionScript 3.0 není, protože zde se využívá proměnná skutečně bez definovaného typu. Proměnné bez anotace typu jsou nyní považovány za proměnné bez typu. Chcete-li čtenářům kódu objasnit, že vaším záměrem je ponechat proměnnou bez definice typu, můžete pro anotaci typu použít symbol hvězdičky (*), což je stejné, jako byste anotaci typu vynechali. Následující příklad ukazuje dva shodné příkazy, které deklarují proměnnou bez typu x: var x var x:*
Poslední aktualizace 12.5.2011
55
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
Pouze proměnné bez typu mohou uchovávat hodnoty undefined. Jestliže se pokusíte přiřadit hodnotu undefined proměnné mající datový typ, převede běhový modul hodnotu undefined na výchozí hodnotu daného datového typu. Pro instance datového typu Object je výchozí hodnota null, což znamená, že pokud se instanci třídy Object pokusíte přiřadit hodnotu undefined, bude tato hodnota převedena na hodnotu null.
Převody typu Převod typu nastává v případě, že hodnota je transformované do hodnoty odlišného datového typu. Převody typu mohou být buď implicitní, nebo explicitní. Za běhu se někdy provádí implicitní převod, rovněž označovaný jako donucení. Bude-li například proměnné datového typu Boolean přiřazena hodnota 2, bude hodnota 2 převedena na booleovskou hodnotu true před tím, než bude tato hodnota přiřazena proměnné. Explicitní převod, nazývaný obsazování, nastává v případě, že kód vydává instanci kompilátoru, aby s proměnnou jednoho datového typu zacházel, jako by náležela jinému datovému typu. Když se procesu účastní primitivní hodnoty, obsazování ve skutečnosti převede hodnoty z jednoho datového typu na jiný. Chcete-li obsadit objekt jiným datovým typem, vložte jej do závorek a předsaďte název nového typu. Například následující kód přebírá booleovskou hodnotu a obsahuje ji celočíselnou hodnotou: var myBoolean:Boolean = true; var myINT:int = int(myBoolean); trace(myINT); // 1
Implicitní převody Implicitní převody nastávají v době spuštění v mnoha kontextech:
• Během příkazu přiřazení • Když jsou hodnoty předány jako argumenty funkce • Když jsou hodnoty vráceny z funkcí • Ve výrazech využívajících jisté operátory, například přidání operátoru (+) Pro uživatelem definované typy uspějí implicitní převody tam, kde je převáděná hodnota instancí cílové třídy nebo třídy, které je odvozena od své cílové třídy. Pokud je implicitní převod neúspěšný, je signalizována chyba. Například následující kód obsahuje úspěšný i neúspěšný implicitní převod. class A {} class B extends A {} var objA:A = new A(); var objB:B = new B(); var arr:Array = new Array(); objA = objB; // Conversion succeeds. objB = arr; // Conversion fails.
Pro primitivní typy jsou implicitní převody zpracovávány voláním stejných vnitřních převodních algoritmů, které jsou volány explicitními převodními funkcemi. Explicitní převody Je užitečné používat explicitní převody nebo obsazování, když kompilujete kód v přísném režimu, protože se mohou vyskytovat okamžiky, kdy nechcete, aby neshoda typu vygenerovala chybu v době kompilace. Tak tomu může být v případě, že vynucení převede vaše hodnoty správně v době spuštění. Například při práci s daty přijatým z formuláře se můžete spolehnout na vynucení a převést jisté řetězcové hodnoty na numerické hodnoty. Následující kód vygeneruje chybu v době kompilace, ale kód bude ve standardním režimu pracovat správně:
Poslední aktualizace 12.5.2011
56
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
var quantityField:String = "3"; var quantity:int = quantityField; // compile time error in strict mode
Pokud chcete pokračovat v přísném režimu, ale chcete převést řetězec na celočíselnou hodnotu, můžete použít explicitní převod a to takto: var quantityField:String = "3"; var quantity:int = int(quantityField); // Explicit conversion succeeds.
Obsazení do int, uint a Number Můžete obsadit kterýkoliv datový typ jedním ze tří typů čísel: int, uint a Number. Nelze-li číslo z nějakého důvodu převést, přiřadí se datovým typům int a unint výchozí hodnota 0 a datovému typu Number se přiřadí výchozí hodnota NaN. Pokud převedete na číslo booleovskou hodnotu, z hodnoty true se stane hodnota 1 a z false bude 0. var myBoolean:Boolean = true; var myUINT:uint = uint(myBoolean); var myINT:int = int(myBoolean); var myNum:Number = Number(myBoolean); trace(myUINT, myINT, myNum); // 1 1 1 myBoolean = false; myUINT = uint(myBoolean); myINT = int(myBoolean); myNum = Number(myBoolean); trace(myUINT, myINT, myNum); // 0 0 0
Řetězcové hodnoty obsahující pouze číslice mohou být úspěšně převedeny do jednoho z číselných typů. Číselný typ může také převést řetězce, které vypadají jako záporná číselná hodnota nebo šestnáctková hodnota (například 0x1A). Proces převodu ignoruje prázdné znaky na začátku a na konci v hodnotě řetězce. Můžete také obsadit řetězce, které vypadají jako desetinná čísla a to pomocí Number(). Zahrnutí desetinné čárky způsobuje, že uint() a int() vrátí celočíselnou hodnotu a zkrátí se desetinná hodnota a znaky za ní následující. Například následující hodnoty řetězce mohou obsadit čísla. trace(uint("5")); // 5 trace(uint("-5")); // 4294967291. It wraps around from MAX_VALUE trace(uint(" 27 ")); // 27 trace(uint("3.7")); // 3 trace(int("3.7")); // 3 trace(int("0x1A")); // 26 trace(Number("3.7")); // 3.7
Hodnoty řetězce obsahující nečíselné znaky vrátí 0, když jsou obsazeny s int() nebo uint() a NaN, když jsou obsazeny Number(). Proces převodu ignoruje prázdné znaky na začátku a na konci, ale vrací 0 nebo NaN, pokud má řetězec prázdný znak oddělující dvě čísla. trace(uint("5a")); // 0 trace(uint("ten")); // 0 trace(uint("17 63")); // 0
V jazyce ActionScript 3.0 funkce Number() již nepodporuje oktálová čísla, nebo čísla s osmičkovým základem. Pokud řetězec s nulou na začátku předáte v jazyce ActionScript 2.0 funkci Number(), číslo bude interpretováno jako oktálové číslo a převedeno na desítkovou hodnotu. V případě funkce Number() v jazyce ActionScript 3.0 tomu tak není, zde se první nula ignoruje. Například následující kód vygeneruje jiný výstup při kompilování v různých verzích jazyka ActionScript: trace(Number("044")); // ActionScript 3.0 44 // ActionScript 2.0 36
Poslední aktualizace 12.5.2011
57
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
Obsazení není nutné, pokud hodnota jednoho číselného typu bude přiřazena proměnné s jiným číselným typem. I v přísném režimu jsou číselné typy implicitně převáděny na jiné číselné typy. To znamená, že v některých případech se mohou vyskytnout neočekávané hodnoty, pokud je překročen rozsah typu. Všechny následující příklady jsou kompilovány v přísném režimu, ačkoliv některé generují neočekávané hodnoty: var myUInt:uint = -3; // Assign int/Number value to uint variable trace(myUInt); // 4294967293 var myNum:Number = sampleUINT; // Assign int/uint value to Number variable trace(myNum) // 4294967293 var myInt:int = uint.MAX_VALUE + 1; // Assign Number value to uint variable trace(myInt); // 0 myInt = int.MAX_VALUE + 1; // Assign uint/Number value to int variable trace(myInt); // -2147483648
Následující tabulka uvádí souhrn výsledků obsazení do datového typu Number, int nebo uint z jiného datového typu. Datový typ nebo hodnota Výsledek převodu na typ Number, int nebo uint Booleovské
Pokud je hodnota true, pak 1; jinak 0.
Datum
Vnitřní vyjádření objektu Date, což je počet milisekund od půlnoci 1. ledna 1970 univerzálního času.
null
0
Objekt
Pokud je instance null a převedená na Number, pak NaN; jinak 0.
Řetězec
Číslo, pokud lze řetězec převést na číslo, v opačném případě hodnota NaN, pokud je převeden na datový typ Number, nebo 0, je-li převeden na datový typ int nebo uint.
undefined
Pokud převedeno na Number, pak NaN; pokud převedeno na int nebo uint, tak 0.
Obsazení do Booleovské hodnoty Obsazení do Booleovské hodnoty z kteréhokoliv číselného datového typu int, unit a Number) vede k hodnotě false, pokud je číselná hodnota 0, a v ostatních případech k hodnotě true. Pro datový typ Number hodnota NaN také vede k false. Následující příklad ukazuje výsledky obsazení čísel -1, 0 a 1: var myNum:Number; for (myNum = -1; myNum<2; myNum++) { trace("Boolean(" + myNum +") is " + Boolean(myNum)); }
Výstup příklad ukazuje, že ze tří čísel pouze 0 vrací hodnotu false: Boolean(-1) is true Boolean(0) is false Boolean(1) is true
Obsazení do Booleovské hodnoty z hodnoty String vrací false v případě, že řetězec je null nebo prázdný řetězec (""). V opačném případě vrací true.
Poslední aktualizace 12.5.2011
58
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
var str1:String; // Uninitialized string is null. trace(Boolean(str1)); // false var str2:String = ""; // empty string trace(Boolean(str2)); // false var str3:String = " "; // white space only trace(Boolean(str3)); // true
Obsazení do Booleovské hodnoty z instance třídy Object vrací false, pokud je instance null; jinak vrací true: var myObj:Object; // Uninitialized object is null. trace(Boolean(myObj)); // false myObj = new Object(); // instantiate trace(Boolean(myObj)); // true
Booleovská proměnná je v přísném režimu zpracovávána zvláštním způsobem v tom, že booleovské proměnné můžete přiřadit hodnoty kteréhokoliv datového typu bez obsazování. Implicitní vynucení ze všech datových typů do booleovského datového typu nastává i v přísném režimu. Jinými slovy na rozdíl od téměř všech ostatních datových typů obsazení do booleovské hodnoty není nutné k tomu, abyste se vyhnuli chybám přísného režimu. Následující příklad jsou všechny kompilovány v přísném režimu a chovají se v době spuštění podle očekávání. var myObj:Object = new Object(); // instantiate var bool:Boolean = myObj; trace(bool); // true bool = "random string"; trace(bool); // true bool = new Array(); trace(bool); // true bool = NaN; trace(bool); // false
Následující tabulka uvádí souhrn výsledků obsazení do datového typu Boolean z jiných datových typů. Datový typ nebo hodnota
Výsledky převodu do booleovské hodnoty
Řetězec
false, pokud je hodnota null nebo prázdný řetězec (""); jinak true.
null
false
Number, int nebo uint
false, pokud je hodnota NaN nebo 0; jinak true.
Objekt
false, pokud je instance null; jinak true.
Obsazení do String Obsazení do datového typu String z kteréhokoliv číselného datového typu vrací řetězcové vyjádření čísla. Obsazení do datového typu String z booleovské hodnoty vrací řetězec"true", pokud je hodnota true, a řetězec "false", pokud je hodnota false. Obsazení do datového typu String z instance třídy Object vrací řetězec "null", pokud je instance null. Jinak obsazení do datového typu String z třídy Object vrací řetězec "[object Object]". Obsazení do datového typu String z instance třídy Array vrací řetězec tvořený seznamem všech prvků pole oddělených čárkami. Například následující datový typ String vrací jeden řetěze obsahující všechny tři prvky pole: var myArray:Array = ["primary", "secondary", "tertiary"]; trace(String(myArray)); // primary,secondary,tertiary
Poslední aktualizace 12.5.2011
59
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
Obsazení do datového typu String z instance třídy date vrací řetězec vyjadřující datum, které instance obsahuje. Například následující příklad vrací vyjádření instance třídy date (výstup ukazuje výsledek pro pacifický letní čas): var myDate:Date = new Date(2005,6,1); trace(String(myDate)); // Fri Jul 1 00:00:00 GMT-0700 2005
Následující tabulka uvádí souhrn výsledků obsazení do datového typu String z jiných datových typů. Datový typ nebo hodnota
Výsledky převodu do řetězce
Pole
Řetězec tvořený všemi elementy pole.
Booleovské
"true" nebo "false"
Datum
Řetězcové vyjádření objektu Date.
null
"null"
Number, int nebo uint
Řetězcové vyjádření čísla.
Objekt
Pokud je instance null, "null"; jinak "[object Object]".
Syntaxe Syntaxe jazyka definuje soubor pravidel, které musí být dodrženy při zapisování spustitelného kódu.
Rozlišování velkých a malých písmen Jazyk ActionScript 3.0 využívá rozlišování velkých a malých písmen. Identifikátory, které se liší pouze velkým/malým písmem, jsou považovány za odlišné identifikátory. Například následujíc kódy vytváří dvě různé proměnné var num1:int; var Num1:int;
Tečková syntaxe Operátor tečka (.) poskytuje způsob přístupu k vlastnosti a metodě objektu. Pomocí tečkové syntaxe můžete odkazovat na vlastnost třídy nebo metodu pomocí názvu instance, za kterým následující operátor tečka a název vlastnosti nebo metody. Například zvažte následující definici třídy: class DotExample { public var prop1:String; public function method1():void {} }
Pomocí tečkové syntaxe můžete přistupovat k vlastnosti prop1 a metodě method1() pomocí instance vytvořené následujícím kódem: var myDotEx:DotExample = new DotExample(); myDotEx.prop1 = "hello"; myDotEx.method1();
Tečkovou syntaxi můžete použít při definování balíčků. Operátor tečka můžete použít k odkazování na vnořené balíčky. Například třída EventDispatcher spočívá uvnitř balíčku pojmenovaném events, který je vnořen do balíčku pojmenovaného flash. Pomocí výrazu následujícího můžete odkazovat na balíček events: flash.events
Poslední aktualizace 12.5.2011
60
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
Pomocí následujícího výrazu můžete také odkazovat na třídu EventDispatcher: flash.events.EventDispatcher
Lomítková syntaxe Lomítková syntaxe není v jazyce ActionScript 3.0 podporována. Lomítková syntaxe byla používána v dřívějších verzích jazyka ActionScript pro označení cesty filmového klipu nebo proměnné.
Literály Literál je hodnota zobrazující se přímo ve vašem kódu. Následující příklady jsou všechno literály: 17 "hello" -3 9.4 null undefined true false
Literály mohou být také seskupeny do složených literálů. Literálová pole jsou uložena mezi závorkami ([]) a k oddělení prvků pole používají čárku. Literálové pole lze použít pro inicializaci pole. Následující příklady zobrazují dvě pole, která jsou inicializována pomocí literálových polí. Můžete použít příkaz new a předat složený literál jako parametr do konstruktoru třídy Array, ale můžete také přiřadit literálové hodnoty přímo při vytváření instancí následujících klíčových tříd jazyka ActionScript: Object, Array, String, Number, int, uint, XML, XMLList a Boolean. // Use new statement. var myStrings:Array = new Array(["alpha", "beta", "gamma"]); var myNums:Array = new Array([1,2,3,5,8]); // Assign literal directly. var myStrings:Array = ["alpha", "beta", "gamma"]; var myNums:Array = [1,2,3,5,8];
Literály mohou být také použity pro inicializaci generického objektu. Generický objekt je instancí třídy Object. Literálové objekty jsou uvedeny ve složených závorkách ({}) a k oddělení vlastností objektu používají čárku. Každá vlastnost je deklarovaná znakem dvojtečky (:), která odděluje název vlastnosti od její hodnoty. Generický objekt můžete vytvořit pomocí příkazu new a předat literálový objekt jako parametr do konstruktoru třídy Object, nebo můžete přiřadit literálový objekt přímo instanci, kterou deklarujete. Následující příklad ukazuje dva alternativní způsoby vytváření nového generického objektu a inicializace objektu s třemi vlastnostmi (propA, propB a propC), každá z těchto hodnot je nastavena na 1, 2 a 3: // Use new statement and add properties. var myObject:Object = new Object(); myObject.propA = 1; myObject.propB = 2; myObject.propC = 3; // Assign literal directly. var myObject:Object = {propA:1, propB:2, propC:3};
Poslední aktualizace 12.5.2011
61
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
Další témata nápovědy Práce s řetězci Používání regulárních výrazů Inicializace proměnných XML
Středníky Středník (;) můžete použít k ukončení příkazu. Případně pokud středník vynecháte, bude kompilátor předpokládat, že každá řádka kódu představuje jeden příkaz. Protože mnoho programátorů je zvyklých na středník jako znak ukončení příkazu, může být snazší kód číst, pokud jej budete používat k ukončení příkazů konzistentně. Použití středníku k ukončení příkazu umožňuje vložení více než jednoho příkazu do jedné řádky, ale to však může kód znepřehlednit.
Závorky Závorky (()) můžete v jazyce ActionScript 3.0 použít třemi způsoby. Za prvé, závorky můžete použít pro změnu pořadí operací ve výrazu. Operace seskupené uvnitř závorek jsou vždy vykonávány jako první. Například závorky jsou použité pro změnu pořadí operací v následujícím kódu: trace(2 + 3 * 4); // 14 trace((2 + 3) * 4); // 20
Za druhé, závorky můžete použít s čárkou (,) pro vyhodnocení řady výrazů a vrácení výsledků konečného výrazu, jak je vidět na následujícím příkladu: var a:int = 2; var b:int = 3; trace((a++, b++, a+b)); // 7
Za třetí, závorky můžete použít jako funkce nebo metody, jak je vidět na následujícím příkladu, které předají hodnotu String funkci trace(): trace("hello"); // hello
Poznámky Kód jazyka ActionScript 3.0 podporuje dva typy komentářů: jednořádkový a víceřádkový. Tyto mechanismy komentářů jsou podobné jazykům C++ a Java. Kompilátor bude ignorovat text označený jako komentář. Jednořádkové komentáře začínají dopředným lomítkem (//) a pokračují na konec řádky. Například následující kód obsahuje jednořádkový komentář: var someNumber:Number = 3; // a single line comment
Víceřádkový komentář začíná dopředným lomítkem a hvězdičkou(/*) a končí hvězdičkou a dopředným lomítkem (*/). /* This is multiline comment that can span more than one line of code. */
Poslední aktualizace 12.5.2011
62
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
Klíčová slova jsou vyhrazená slova Vyhrazená slova jsou slova, která nemůžete použít jako identifikátory v kódu, protože jsou vyhrazena pro použití jazykem ActionScript. Vyhrazená slova zahrnují lexikální klíčová slova, která jsou vyňata z jmenného prostoru programu kompilátorem. Kompilátor nahlásí chybu, pokud lexikální klíčová slova použijete jako identifikátor. Následující tabulka uvádí seznam lexikálních klíčových slov jazyka ActionScript 3.0. as
break
case
catch
class
const
continue
default
delete
do
else
extends
false
finally
for
function
if
implements
import
in
instanceof
interface
internal
is
native
new
null
package
private
protected
public
return
super
switch
this
throw
to
true
try
typeof
use
var
void
while
with
Existuje malá sada klíčových slov, nazvaných syntaktická klíčová slova, která mohou být použita jako identifikátory, ale mají v jistém kontextu speciální význam. Následující tabulka uvádí seznam syntaktických klíčových slov jazyka ActionScript 3.0. each
get
set
namespace
include
dynamic
final
native
override
static
Existuje také několik identifikátorů, které jsou někdy odkazovány jako budoucí vyhrazená slova. Tyto identifikátory nejsou jazykem ActionScript 3.0 vyhrazeny, ale některé z nich mohou být použita jako klíčová slova softwarem, který jazyk ActionScript 3.0 obsahuje. Může být možné mnoho z těchto identifikátorů ve vašem kódu použít, ale společnost Adobe doporučuje je nepoužívat, protože se mohou jako klíčová slova objevit v následujících verzích jazyka. abstract
boolean
byte
cast
char
debugger
double
enum
export
float
goto
intrinsic
long
prototype
short
synchronized
throws
to
transient
type
virtual
volatile
Poslední aktualizace 12.5.2011
63
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
Konstanty Jazyk ActionScript 3.0 podporuje příkaz const, který můžete použít k vytváření konstant. Konstanty jsou vlastnosti s pevnou hodnotu, kterou nelze změnit. Konstantě můžete přiřadit hodnotu pouze jednou a přiřazení musí být provedeno v blízkosti deklarace konstanty. Pokud je například konstanta deklarována jako člen třídy, můžete přiřadit hodnotu této konstantě pouze jako součást deklarace nebo uvnitř konstruktoru třídy. Následující kód deklarujete dvě konstanty. První konstanta MINIMUM, má hodnotu přiřazenou jako součást příkazu deklarace. Druhá konstanta, MAXIMUM, má hodnotu přiřazenou v konstruktoru. Povšimněte si, že tento příklad se kompiluje pouze ve standardním režimu, protože v přísném režimu umožňuje přiřazení hodnoty konstanty pouze v době inicializace. class A { public const MINIMUM:int = 0; public const MAXIMUM:int; public function A() { MAXIMUM = 10; } } var a:A = new A(); trace(a.MINIMUM); // 0 trace(a.MAXIMUM); // 10
Pokud se pokusíte přiřadit počáteční hodnotu konstantě jiným způsobem, dojde k chybě. Pokud se například pokusíte nastavit počáteční hodnotu MAXIMUM vně třídy, dojde k chybě v čase zpracování. class A { public const MINIMUM:int = 0; public const MAXIMUM:int; } var a:A = new A(); a["MAXIMUM"] = 10; // run-time error
Jazyk ActionScript 3.0 definuje široké rozpětí konstant, které můžete použít. Na základě konvence konstanty v jazyce ActionScript používají všechna velká písmena, se slovy oddělenými podtržítkem (_). Například definice třídy MouseEvent používá tuto konvenci pojmenování pro své konstanty, každá z nich vyjadřuje událost související se vstupem od myši: package flash.events { public class MouseEvent extends Event { public static const CLICK:String = "click"; public static const DOUBLE_CLICK:String = "doubleClick"; public static const MOUSE_DOWN:String = "mouseDown"; public static const MOUSE_MOVE:String = "mouseMove"; ... } }
Poslední aktualizace 12.5.2011
64
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
Operátory Operátory jsou speciální funkce, které mohou mít jeden nebo více operandů a vrací hodnotu. Operand je hodnota, obvykle literál, proměnná nebo výraz, kterou operátor používá jako vstup. Například v následujícím kódu doplnění (+) a násobení (*) operátorů je použito s třemi literálovými operandy (2, 3, a 4) a vrací hodnotu. Hodnota je pak použita operátorem přiřazení (=) k přiřazení vrácené hodnoty, 14, proměnné sumNumber. var sumNumber:uint = 2 + 3 * 4; // uint = 14
Operátory mohou být ternární, binární nebo unární. Unární operátor má jediný operand. Například přírůstkový operátor (++) je unárním operátorem, protože má jenom jeden operand. Binární operátor má dva operandy. Například operátor dělení (/) má dva operandy. Ternární operátor má tři operandy. Například operátor podmínky (?:) má tři operandy. Některé operátory jsou přetížené, což znamená, že se chovají odlišně v závislosti na typu nebo počtu operandu, které jsou jim předané. Operátor sčítání (+) je příkladem přetíženého operátoru, který se chová odlišně v závislosti na datovém typu operandu. Pokud jsou oba operandy čísly, operátor sčítání vrací součet hodnot. Pokud jsou oba operandy řetězce, operátor sčítání vrací zkrácení obou operandů. Následující příklad kódu ukazuje, jak se operátor chová odlišně v závislosti na operandech: trace(5 + 5); // 10 trace("5" + "5"); // 55
Operátory se mohou také chovat odlišně na základě počtu operandů jim předaných. Operátor odčítání (-) je unární i binární operátor. Pokud je předán pouze jediný operand, operátor odčítání neguje operand a vrací výsledek. Po předání dvou operandů operátor odčítání vrací rozdíl mezi operandy. Následující příklad ukazuje operátor odčítání, použitý nejprve jako unární, pak jako binární operátor. trace(-3); // -3 trace(7 - 2); // 5
Přednost a asociativita operátorů Přednost a asociativita operátorů stanoví pořadí, ve kterém jsou operátory zpracovány. I když může vypadat přirozené všem, kteří jsou seznámeni s aritmetikou, že kompilátor zpracovává násobení (*) před sčítáním (+), vyžaduje kompilátor specifické instrukce o tom, které operátory má zpracovat jako první. Takové pokyny jsou souhrnně popisovány jako přednost operátorů. V jazyce ActionScript definuje výchozí operátor přednost, kterou můžete změnit pomocí závorek (()). Například následující kód mění výchozí přednost z předchozího příklad tak, aby donutil kompilátor zpracovat operátor sčítání před operátorem násobení: var sumNumber:uint = (2 + 3) * 4; // uint == 20
Můžete se setkat se situacemi, ve kterých mají dva nebo více operátorů stejnou přednost a jsou uvedeny ve stejném výrazu. V těchto případech kompilátor používá pravidlo asociativity ke stanovení, který operátor má být zpracován jako první. Všechny binární operátor, kromě operátorů přiřazení, jsou asociativní zleva, což znamená, že operátory vlevo jsou zpracovány před operátory vpravo. Operátory přiřazení a podmínkové operátory (?:) jsou zprava asociativní, což znamená, že operátory vpravo jsou zpracovány před operátory vlevo. Například uvažujme operátory menší než (<) a větší než (>), které mají stejnou přednost. Pokud jsou oba operátory použity ve stejném výrazu, operátor na levé straně je zpracován jako první, protože oba operátory jsou asociativní zleva. To znamená, že následující dva příkazy poskytnou stejný výsledek: trace(3 > 2 < 1); // false trace((3 > 2) < 1); // false
Poslední aktualizace 12.5.2011
65
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
Operátor větší než je zpracován jako první, což vede k hodnotě true, protože operand 3 je větší než operand 2. Hodnota true je pak předána operátoru menší než společně s operandem 1. Následující kód představuje tento mezistav: trace((true) < 1);
Operátor menší než převádí hodnotu true na numerickou hodnotu 1 a porovnává tuto numerickou hodnotu s druhým operandem 1 a vrací hodnotu false (hodnota 1 není menší než 1). trace(1 < 1); // false
Pomocí operátoru závorka můžete změnit výchozí asociativitu zleva. Kompilátoru můžete vydat pokyn zpracovat operátor menší než nejprve jeho umístěním do závorek i s jeho operandy. Následující příklad používá operátor závorka k dosažení jiného výsledku pomocí stejných čísel, jako v předchozím příkladu: trace(3 > (2 < 1)); // true
Operátor menší než je zpracován jako první, což vede k hodnotě false, protože operand 2 není menší než operand 1. Hodnota false je pak předána operátoru větší než společně s operandem 3. Následující kód představuje tento mezistav: trace(3 > (false));
Operátor větší než převede hodnotu false na numerickou hodnotu 0 a porovná tuto numerickou hodnotu s druhým operandem 3 a vrátí hodnotu true (hodnota 3 je větší než 0). trace(3 > 0); // true
Následující tabulka uvádí operátory pro jazyk ActionScript 3.0 v pořadí snižující se přednosti. Každá řádka v tabulce obsahuje operátory stejné přednosti. Každý řádka operátorů má vyšší přednost, než řádka následující v tabulce za ní. Skupina
Operátory
Primární operátory
[] {x:y} () f(x) new x.y x[y] <>> @ :: ..
Příponové operátory
x++ x--
Unární operátory
++x --x + - ~ ! delete typeof void
Multiplikativní operátory
* / %
Aditivní
+ -
Bitové operátory posunutí
<< >> >>>
Relační operátory
< > <= >= as in instanceof is
Rovnost
== != === !==
Bitový operátor AND
&
Bitový operátor XOR
^
Bitový operátor OR
|
Logický operátor AND
&&
Logický operátor OR
||
Podmíněný
?:
Přiřazení
= *= /= %= += -= <<= >>= >>>= &= ^= |=
Čárka
,
Poslední aktualizace 12.5.2011
66
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
Primární operátory Primární operátory zahrnují ty, které jsou použity pro vytvoření literálů Array a Object, seskupení výrazů, volání funkcí, konkretizaci instancí třídy a pro přístup k vlastnostem. Všechny primární operátory uvedené v následující tabulce mají stejnou přednost. Operátory, které jsou součástí specifikace E4X, jsou označeny poznámkou (E4X). Operátor
Provedená operace
[]
Inicializace pole
{x:y}
Inicializace objektu
()
Seskupení výrazů
f(x)
Volání funkce
new
Volání konstruktoru
x.y x[y]
Přístup k vlastnostem
<>>
Inicializace objektu XMLList (E4X)
@
Přístup k atributu (E4X)
::
Kvalifikace názvu (E4X)
..
Přistupuje k dceřinému prvku XML (E4X)
Příponové operátory Příponové operátory vezmou jeden operand a provedou zvýšení nebo snížení jeho hodnoty. I když tyto operátory jsou unárními operátory, jsou klasifikovány samostatně od zbytku unárních operátorů, díky jejich vyšší přednosti a zvláštnímu chování. Když je použít příponový operátor jako součást větší výrazu, hodnota výrazu je vrácena před zpracováním příponového operátoru. Například následující kód zobrazuje, jak je vracena hodnota xNum++ před svým zvýšením: var xNum:Number = 0; trace(xNum++); // 0 trace(xNum); // 1
Všechny příponové operátory uvedené v následující tabulce mají stejnou přednost. Operátor
Provedená operace
++
Zvýšení hodnoty (přípona)
--
Snížení hodnoty (přípona)
Unární operátory Unární operátory pracující s jedním operandem. Operátory zvýšení hodnoty (++) a snížení hodnoty (--) v této skupině jsou předponovéoperátory, což znamená, že se ve výrazu zobrazují před operandem. Předponové operátory se liší od svých protějšků, příponových operátorů, a to v tom, že operace zvýšení nebo snížení hodnoty je dokončena předtím, než je vrácena hodnota celkového výrazu. Například následující kód zobrazuje, jak je vracena hodnota ++xNum po svém zvýšení:
Poslední aktualizace 12.5.2011
67
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
var xNum:Number = 0; trace(++xNum); // 1 trace(xNum); // 1
Všechny unární operátory uvedené v následující tabulce mají stejnou přednost. Operátor
Provedená operace
++
Zvýšení hodnoty (předpona)
--
Snížení hodnoty (předpona)
+
Unární operátor +
-
Unární operátor - (negace)
!
Logický operátor NOT
~
Bitový operátor NOT
delete
Odstranění vlastnosti
typeof
Vrácení typu informace
void
Vrací nedefinovanou hodnotu
multiplikativní operátory Multiplikativní operátory vezmou dva operandy a provedou s nimi násobení, dělení nebo výpočty s operandem modulu. Všechny multiplikativní operátory uvedené v následující tabulce mají stejnou přednost. Operátor
Provedená operace
*
Násobení
/
Dělení
%
Modulo
Aditivní operátory Aditivní operátory vezmou dva operandy a provedou sčítání nebo odčítání. Všechny aditivní operátory uvedené v následující tabulce mají stejnou přednost. Operátor
Provedená operace
+
Sčítání
-
Odčítání
Bitové operátory posunutí Bitové operátory posunutí vezmou dva operandy a provedou s nimi posunutí bitů prvního operandu v rozsahu specifikovaném druhým operandem. Všechny bitové operátory posunutí uvedené v následující tabulce mají stejnou přednost.
Poslední aktualizace 12.5.2011
68
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
Operátor
Provedená operace
<<
Bitové posunutí vlevo
>>
Bitové posunutí vpravo
>>>
Bitové posunutí vpravo, bez znaménka
Relační operátory Relační operátory vezmou dva operandy a provedou porovnání jejich hodnot a vrátí booleovskou hodnotu. Všechny relační operátory uvedené v následující tabulce mají stejnou přednost. Operátor
Provedená operace
<
Menší než
>
Větší než
<=
Menší než nebo rovno
>=
Větší než nebo rovno
as
Kontrola datového typu
in
Kontrola vlastností objektu
instanceof
Kontrola řetězu prototypu
is
Kontrola datového typu
Operátory rovnosti Operátory rovnosti vezmou dva operandy a provedou porovnání jejich hodnot a vrátí booleovskou hodnotu. Všechny relační operátory uvedené v následující tabulce mají stejnou přednost. Operátor
Provedená operace
==
Rovnost
!=
Nerovnost
===
Přesná rovnost
!==
Přesná nerovnost
Bitové logické operátory Bitové logické operátory vezmou dva operandy a provedou s nimi logické operace na úrovni bitů. Bitové logické operátory se odlišují svou předností a jsou uvedeny v následující tabulce v pořadí snižující se přednosti: Operátor
Provedená operace
&
Bitový operátor AND
^
Bitový operátor XOR
|
Bitový operátor OR
Poslední aktualizace 12.5.2011
69
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
Logické operátory Logické operátory vezmou dva operandy a vrátí booleovskou hodnotu. Logické operátory se odlišují svou předností a jsou uvedeny v následující tabulce v pořadí snižující se přednosti: Operátor
Provedená operace
&&
Logický operátor AND
||
Logické OR
Podmínečný operátor Podmínečný operátor je ternární operátor, což znamená, že pracuje se třemi operandy. Podmínečný operátor je rychlou metodou aplikace podmíněného příkazu if..else. Operátor
Provedená operace
?:
Podmínečný
Operátory přiřazení Operátory přiřazení vezmou dva operandy a přiřadí hodnotu jednomu z nich, na základě hodnoty druhého operandu. Všechny operátory přiřazení uvedené v následující tabulce mají stejnou přednost. Operátor
Provedená operace
=
Přiřazení
*=
Přiřazení násobení
/=
Přiřazení dělení
%=
Přiřazení modulo
+=
Přiřazení sčítání
-=
Přiřazení odečítání
<<=
Přiřazení bitového posunutí vlevo
>>=
Přiřazení bitového posunutí vpravo
>>>=
Přiřazení bitového posunutí vpravo, bez znaménka
&=
Přiřazení bitového operátoru AND
^=
Přiřazení bitového operátoru XOR
|=
Přiřazení bitového operátoru OR
Podmíněné příkazy Jazyk ActionScript 3.0 poskytuje tři základní podmíněné příkazy, které můžete používat pro ovládání chodu programu.
Poslední aktualizace 12.5.2011
70
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
if..else Podmíněný příkaz if..else umožňuje testovat podmínku a vykonávat blok kódu v případě, že podmínka existuje, nebo vykonávat alternativní blok kódu, pokud podmínka neexistuje. Například následující kód testuje, zda hodnota x přesahuje 20, a vygeneruje funkci trace() v případě, že ano, nebo vygeneruje jinou funkci trace(), pokud ne: if (x > 20) { trace("x is > 20"); } else { trace("x is <= 20"); }
Pokud nechcete vykonat alternativní blok kódu, můžete použít příkaz if bez příkazu else.
if..else if Pomocí podmíněného příkazu if..else if můžete testovat více než jednu podmínku. Například následující kód testuje nejenom, zda hodnota x přesahuje 20, ale také, zda hodnota x je záporná: if (x > 20) { trace("x is > 20"); } else if (x < 0) { trace("x is negative"); }
Pokud za příkazem if nebo else následuje pouze jeden příkaz, nemusí být tento příkaz vložen ve složených závorkách. Například následující kód nepoužívá složené závorky: if (x > 0) trace("x else if (x < trace("x else trace("x
is positive"); 0) is negative"); is 0");
Společnost Adobe však doporučuje používat složené závorky vždy, protože pokud budou později příkazy přidány do podmíněného příkazu bez složených závorek, může dojít k neočekávanému chování. Například v následujícím kódu se hodnota positiveNums zvyšuje o 1 bez ohledu na to, zda je podmínka vyhodnocena true: var x:int; var positiveNums:int = 0; if (x > 0) trace("x is positive"); positiveNums++; trace(positiveNums); // 1
Poslední aktualizace 12.5.2011
71
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
switch Příkaz switch je užitečný v případě, že máte několik cest vykonání kódu, které závisí na stejném podmíněném výrazu. Poskytuje funkci podobnou dlouhé řadě příkazů if..else if, ale snáze se čte. Namísto testování podmínky s ohledem na booleovskou hodnotu, příkaz switch vyhodnocuje výraz a používá výsledek ke stanovení, který blok kódu je nutné vykonat. Bloky kódu začíná příkazem case a končí příkazem break. Například následující příkazy switch vytisknou den v týdnu na základě čísla dne, vráceného metodou Date.getDay(): var someDate:Date = new Date(); var dayNum:uint = someDate.getDay(); switch(dayNum) { case 0: trace("Sunday"); break; case 1: trace("Monday"); break; case 2: trace("Tuesday"); break; case 3: trace("Wednesday"); break; case 4: trace("Thursday"); break; case 5: trace("Friday"); break; case 6: trace("Saturday"); break; default: trace("Out of range"); break; }
Opakování Opakování příkazu umožňuje provádět specifické bloky kódu opakovaně pomocí řady hodnot nebo proměnných. Společnost Adobe doporučuje vždy uzavřít blok kódu do složených závorek ({}). I když lze složené závorky vynechat v případě, že blok kódu obsahuje pouze jeden příkaz, tento postup se nedoporučuje ze stejného důvodu, jako se nedoporučuje pro podmíněné příkazy: zvyšuje pravděpodobnost, že posléze přidané příkazy budou z bloku kódu neúmyslně vyloučeny. Pokud později přidáte příkaz, který chcete zahrnout do bloku kódu, ale zapomenete přidat potřebné složené závorky, příkaz nebude vykonán jako součást opakování cyklu.
Poslední aktualizace 12.5.2011
72
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
for Opakování (cyklus) for umožňuje iterovat proměnnou ve specifickém rozsahu hodnot. Do příkazu for musíte zadat tři výrazy: proměnnou, která je nastavena na počáteční hodnotu, podmíněný příkaz, který stanoví, když cyklus končí, a výraz, který mění hodnotu proměnné po každém cyklu. Například následující příkaz se bude opakovat pětkrát. Hodnota proměnné i začíná na hodnotě 0 a končí na hodnotě 4 a výstup je tvořen čísly 0 až 4, každým na vlastním řádku. var i:int; for (i = 0; i < 5; i++) { trace(i); }
příkaz for..in Příkaz for..in iteruje vlastnosti objektu, nebo prvky pole. Například můžete použít cyklus for..in a iterovat vlastnosti generického objektu (vlastnosti objektu nejsou žádným specifickým způsobem řazeny, takže se mohou zobrazovat ve zdánlivě náhodném pořadí): var myObj:Object = {x:20, y:30}; for (var i:String in myObj) { trace(i + ": " + myObj[i]); } // output: // x: 20 // y: 30
Iterovat můžete také prvky pole: var myArray:Array = ["one", "two", "three"]; for (var i:String in myArray) { trace(myArray[i]); } // output: // one // two // three
Nelze však iterovat přes vlastnosti objektu, pokud se jedná o instanci uzavřené třídy (včetně vestavěných tříd a tříd definovaných uživatelem). Iterovat lze pouze přes vlastnosti dynamické třídy. Také u instancí dynamických tříd lze iterovat pouze přes vlastnosti, které jsou přidány dynamicky.
for each..in Příkaz for each..in iteruje položky sbírky, což mohou být značky v objektu XML nebo XMLList, hodnoty uchovávané vlastnostmi objektu, nebo prvky pole. Například následující výňatek ukazuje, že můžete použít cyklus for each..in k iterování vlastností generického objektu, ale na rozdíl od cyklu for..in iterační proměnná v cyklu for each..in obsahuje hodnotu uchovávanou vlastností namísto názvu vlastnosti:
Poslední aktualizace 12.5.2011
73
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
var myObj:Object = {x:20, y:30}; for each (var num in myObj) { trace(num); } // output: // 20 // 30
Můžete iterovat objekty XML nebo XMLList, jak ukazuje následující příkaz: var myXML:XML = <users> Jane Susan John ; for each (var item in myXML.fname) { trace(item); } /* output Jane Susan John */
Můžete také iterovat prvky pole, jak ukazuje následující příkaz: var myArray:Array = ["one", "two", "three"]; for each (var item in myArray) { trace(item); } // output: // one // two // three
Nemůžete iterovat vlastnosti objektu, pokud je objekt instancí zapouzdřené třídy. Ani pro instance dynamických tříd nemůžete iterovat žádnou pevnou vlastnosti, která je vlastností definovanou jako součást definice třídy.
while Příkaz cyklu while je podobný příkazu if, který se opakuje, dokud má podmínka hodnotu true. Například následující kód produkuje stejný výstup, jako příklad cyklu for: var i:int = 0; while (i < 5) { trace(i); i++; }
Jednou z nevýhod používání cyklu while místo cyklu for je to, že nekonečné cykly se zapisují snáze s cykly while. Příklad kódu cyklu for se nezkompiluje v případě, že vynecháte výraz, který zajistí zvýšení hodnoty proměnné counter, ale příklad cyklu while se zkompiluje, pokud tento krok vynecháte. Bez výrazu, který zajistí zvýšení hodnoty i se cyklus stane nekonečným.
Poslední aktualizace 12.5.2011
74
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
do..while Příkaz cyklu do..while je cyklem while, který zaručuje, že blok kódu je vykonán alespoň jednou, protože podmínka je kontrolována po vykonání bloku kódu. Následující kód zobrazuje jednoduchý příklad cyklu do..while, který generuje výstup i v případě, že podmínka není splněna: var i:int = 5; do { trace(i); i++; } while (i < 5); // output: 5
Funkce Funkce jsou bloky kódu, které provádějí specifické úlohy a mohou být v programu použity opakovaně. V jazyce ActionScript 3.0 existují dva typy funkcí: metody a uzavřené funkce. To, zda je funkce nazvaná metodou nebo uzavřenou funkcí, závisí na kontextu, ve kterém je funkce definována. Funkce se nazývá metoda, pokud ji definujete jako součást definice třídy nebo ji připojíte k instanci objektu. Funkce se nazývá uzavřenou funkcí, pokud je definována jiným způsobem. Funkce byly v jazyce ActionScript vždy extrémně důležité. V jazyce ActionScript 1.0 klíčové slovo class neexistovalo, takže „třídy“ byly definovány funkcemi konstruktoru. I když klíčové slovo class byl od té doby do jazyka přidáno, dobré porozumění funkcím je i nadále důležité, pokud chcete plně využít to, co jazyk nabízí. To může být výzvou programátorům, kteří očekávají, že se funkce ActionScript budou chovat podobně, jako funkce v jazycích jako C++ nebo Java. Ačkoliv základní definice funkce a její volání by nemělo pro zkušené programátory představovat žádnou výzvu, některé pokročilejší vlastnosti funkcí jazyka ActionScript vyžadují podrobnější vysvětlení.
Základní koncepty funkcí Volání funkcí Funkci voláte pomocí jejího identifikátoru, následovaného operátorem závorky (()). Operátor závorky použijete k uzavření parametrů funkce, které chcete funkci odeslat. Například funkce trace() je v jazyce ActionScript 3.0 funkcí nejvyšší úrovně: trace("Use trace to help debug your script");
Pokud voláte funkci bez parametrů, musíte použít prázdný pár závorek. Můžete například použít metodu Math.random(), která nepoužije žádný parametr, a vygenerovat náhodné číslo: var randomNum:Number = Math.random();
Definování vlastních funkcí Existují dva způsoby, jak definovat funkci v jazyce ActionScript 3.0: můžete použít příkaz funkce nebo výraz funkce. Vybraná technika závisí na tom, zda dáváte přednost statickému nebo dynamickému stylu programování. Definujte funkce s příkazy, pokud preferujete statický, nebo přísný režim programování. Definujte funkce s výrazy, pokud k tomu máte specifický důvod. Výrazy funkce jsou častěji používaný v dynamickém, nebo standardním režimu programování.
Poslední aktualizace 12.5.2011
75
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
Příkazy funkce Příkazy funkce jsou upřednostňovanou technikou definování funkcí v přísném režimu. Příkazy funkce začínají klíčovým slovem function, za kterým následuje:
• Název funkce • Parametry, ve formě seznamu odděleného čárkami v závorkách • Tělo funkce, tj. kód v jazyce ActionScript, který má být proveden při volání funkce, uzavřený ve složených závorkách Například následující kód vytvoří funkci, která definuje parametr a pak volá funkci pomocí řetězce „hello“ jako hodnoty parametru: function traceParameter(aParam:String) { trace(aParam); } traceParameter("hello"); // hello
Výrazy funkce Druhým způsobem, jak deklarovat funkci, je použití příkazu přiřazení s výrazem funkce, což se také někdy nazývá literál funkce nebo anonymní funkce. Existuje kompletnější metoda, která byla široce používána v předchozích verzích jazyka ActionScript. Příkaz přiřazení s výrazem funkce začíná klíčovým slovem var, po kterém následuje:
• Název funkce • Operátor dvojtečka (:) • Třída function pro definování datového typu • Operátor přiřazení (=) • Klíčové slovo function • Parametry, ve formě seznamu odděleného čárkami v závorkách • Tělo funkce, tj. kód v jazyce ActionScript, který má být proveden při volání funkce, uzavřený ve složených závorkách Například následujíc kód deklaruje funkci traceParameter pomocí výrazu funkce: var traceParameter:Function = function (aParam:String) { trace(aParam); }; traceParameter("hello"); // hello
Povšimněte si, že nespecifikujete název funkce, jako v příkazu funkce. Dalším důležitým rozdílem mezi výrazy a příkazy funkce je to, že výraz funkce je spíše výrazem než příkazem. To znamená, že výraz funkce nemůže stát samostatně, jako může příkaz funkce. Výraz funkce může být použit pouze jako součást příkazu, obvykle jako příkazu přiřazení. Následující příklad ukazuje výraz funkce, přiřazený prvku pole:
Poslední aktualizace 12.5.2011
76
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
var traceArray:Array = new Array(); traceArray[0] = function (aParam:String) { trace(aParam); }; traceArray[0]("hello");
Výběr mezi příkazy a výrazy Všeobecné pravidlo zní používat příkaz funkce, pokud specifické okolnosti nevyžadují použití výrazu. Příkazy funkce jsou méně kompletní a poskytují konzistentnější spolupráci mezi přísným a standardním režimem, než výrazy funkce. Příkazy funkce se snáze čtou, než výrazy funkce, které obsahují výrazy. Příkazy funkce činí kód stručnějším; jsou méně matoucí, než výrazy funkce, které vyžadují použití klíčových slov var i function. Příkazy funkce umožňují konzistentnější spolupráci mezi dvěma režimy kompilátoru, neboť v přísném i standardním režimu lze použít tečkovou syntaxi k volání metody deklarované pomocí příkazu funkce. To není nutné pravdivé pro metody deklarované výrazem funkce. Například následující kód definuje třídu pojmenovanou Example dvěma metodami: methodExpression(), která je deklarovaná výrazem funkce, a methodStatement(), která je deklarovaná příkazem funkce. V přísném režimu nelze tečkovou syntaxi použít k volání metody methodExpression(). class Example { var methodExpression = function() {} function methodStatement() {} } var myEx:Example = new Example(); myEx.methodExpression(); // error in strict mode; okay in standard mode myEx.methodStatement(); // okay in strict and standard modes
Výrazy funkce jsou vhodnější k programování, které se zaměřuje n a chování programu během jeho spuštění (dynamické). Pokud dáváte přednost použití přísného režimu, ale rovněž potřebujte volat metodu deklarovanou výrazem funkce, použijte jednu z dvou technik. První, můžete zavolat metodu pomocí hranatých závorek ([]) namísto tečky (.) operátor. Následující volání metody je úspěšné v přísném i standardním režimu: myExample["methodLiteral"]();
Druhá, můžete deklarovat celou třídu jako dynamickou třídu. I když toto umožňuje volat metodu pomocí operátoru tečka, nevýhodou je to, že obětujete část funkčnosti přísného režimu pro všechny instance dané třídy. Například kompilátor negeneruje chybu při pokusu o přístup k nedefinované vlastnosti instance dynamické třídy. Existují jisté okolnosti, za kterých jsou výrazy funkce užitečné. Běžné využití výrazu funkce je pro funkce, které jsou používány pouze jednou a pak jsou vyřazeny. Dalším, méně běžným použitím, je připojení funkce k vlastnosti prototypu. Více informací naleznete v části Objekt prototypu. Existují dva drobné rozdíly mezi příkazem a výrazem funkce, které byste měli vzít v úvahu při volbě použité techniky. První rozdíl spočívá v tom, že výrazy funkce neexistují nezávisle jako objekty, s ohledem na správu paměti a čištění uvolněné paměti. Jinými slovy, když přiřadíte výraz funkce jinému objektu, například prvku pole nebo vlastnosti objektu, vytvoříte pouze referenci na tento výraz funkce ve svém kódu. Pokud se pole nebo objekt, k němuž je výraz funkce připojen, dostane mimo rozsah nebo je jinak nedostupný, nebudete již mít přístup k výrazu funkce. Dojde-li k odstranění pole nebo objektu, paměť použitá výrazem funkce bude připravena k čištění uvolněné paměti, což znamená, že paměť bude možné použít pro jiné účely.
Poslední aktualizace 12.5.2011
77
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
Následující příklad ukazuje, že pro výraz funkce nebude tato funkce již dále dostupná, jakmile je odstraněna vlastnost, ke které je výraz přiřazen. Třída Test je dynamická, což znamená, že můžete přidat vlastnosti pojmenovanou functionExp, která uchovává výraz funkce. Funkce functionExp() může být volána operátorem tečka, ale jakmile je vlastnost functionExp odstraněna, funkce již není přístupná. dynamic class Test {} var myTest:Test = new Test(); // function expression myTest.functionExp = function () { trace("Function expression") }; myTest.functionExp(); // Function expression delete myTest.functionExp; myTest.functionExp(); // error
Pokud na druhou stranu bude funkce nejprve definována příkazem funkce, existuje jako vlastní objekt a existuje i poté, co odstraníte vlastnost, ke které byla funkce připojena. Operátor delete je funkční pouze pro vlastnosti objektů, takže i volání pro odstranění funkce stateFunc() samotné nepracuje. dynamic class Test {} var myTest:Test = new Test(); // function statement function stateFunc() { trace("Function statement") } myTest.statement = stateFunc; myTest.statement(); // Function statement delete myTest.statement; delete stateFunc; // no effect stateFunc();// Function statement myTest.statement(); // error
Druhým rozdílem mezi výrazem a příkazem funkce je to, že výraz funkce existuje v rámci rozsahu, ve kterém je definován, včetně příkazů in, které se objevují před příkazem funkce. Výrazy funkce jsou oproti tomu definovány pouze pro následující příkazy. Například následující kód úspěšně volá funkci scopeTest() před jejím definováním: statementTest(); // statementTest function statementTest():void { trace("statementTest"); }
Výrazy funkce nejsou dostupné před definováním, takže následující kód vede k chybě při spuštění kódu: expressionTest(); // run-time error var expressionTest:Function = function () { trace("expressionTest"); }
Vracení hodnot z funkcí Chcete-li, aby funkce vrátila hodnotu, použijte příkaz return následovaný výrazem nebo literálovou hodnotou, kterou chcete vrátit. Například následující kód vrací výraz, představující parametr: function doubleNum(baseNum:int):int { return (baseNum * 2); }
Poslední aktualizace 12.5.2011
78
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
Všimněte si, že příkaz return funkci ukončí, takže jakékoliv příkazy pod příkazem return nebudou vykonány: function doubleNum(baseNum:int):int { return (baseNum * 2); trace("after return"); // This trace statement will not be executed. }
V přísném režimu musíte vrátit hodnotu vhodného typu, protože nevrací platnou hodnotu: Například následující kód generuje v přísném režimu chybu, protože nevrací platnou hodnotu: function doubleNum(baseNum:int):int { trace("after return"); }
Vnořené funkce Funkce můžete vnořovat, což znamená, že funkce mohou být deklarovány uvnitř jiných funkcí. Vnořená funkce je dostupná pouze ve své nadřazené funkci, pokud není odkaz na tuto funkci předán externímu kódu. Například následující kód deklaruje dvě vnořené funkce uvnitř funkce getNameAndVersion(): function getNameAndVersion():String { function getVersion():String { return "10"; } function getProductName():String { return "Flash Player"; } return (getProductName() + " " + getVersion()); } trace(getNameAndVersion()); // Flash Player 10
Když jsou vnořené funkce předány externímu kódu, jsou předány jako uzavřené funkce, což znamená, že funkce si uchovává všechny definice, které jsou v rozsahu při definování funkce. Další informace, viz Rozsah funkce.
Parametry funkce Jazyk ActionScript 3.0 poskytuje některé funkčnosti pro parametry funkcí, které mohou novým programátorům tohoto jazyka připadat jako neobvyklé. I když princip předávání parametrů hodnotou nebo odkazem by měl být většině programátorů znám, objekt arguments a parametr ... (rest) mohou být pro mnoho z nich nové. Předávání argumentů hodnotou nebo odkazem V mnoha programovacích jazycích je důležité porozumět odlišnosti mezi předáváním argumentů hodnotou nebo odkazem; rozdíl může ovlivňovat způsob tvorby kódu. Předání hodnotou znamená, že hodnota argumentu je kopírována do místní proměnné pro použití v rámci funkce. Předání odkazem znamená, že je předán pouze odkaz na argument, místo skutečné hodnoty. Není zhotovena žádná kopie stávajícího argumentu. Místo toho se vytvoří odkaz na proměnnou předaný jako argument a je přiřazen místní proměnné pro použití v rámci funkce. Jako odkaz na proměnnou vně funkce umožňuje místní proměnné změnit hodnotu původní proměnné.
Poslední aktualizace 12.5.2011
79
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
V jazyce ActionScript 3.0 jsou všechny argumenty předávány formou odkazu, protože všechny hodnoty jsou uloženy jako objekty. Nicméně objekty, které náleží primitivním datovým typům, což zahrnuje Boolean, Number, int, uint a String, mají speciální operátory, které jim umožňují chovat se, jako by byly předány hodnotou. Například následující kód vytvoří funkci pojmenovanou passPrimitives(), která definuje dva parametry pojmenované xParam a yParam, obojí typu int. Tyto parametry jsou podobné místním proměnným, deklarovaným uvnitř těla funkce passPrimitives(). Když je zavolána funkce s argumenty xValue a yValue, parametry xParam a yParam jsou inicializovány s odkazy na objekty int zastoupené xValue a yValue. Protože argumenty jsou primitivní, chovají se jako by předaly hodnotu. I když xParam a yParam v počátku obsahují pouze odkazy na hodnotu objektů xValue a yValue, všechny změny proměnných v těle funkce generují nové kopie hodnoty v paměti. function passPrimitives(xParam:int, yParam:int):void { xParam++; yParam++; trace(xParam, yParam); } var xValue:int = 10; var yValue:int = 15; trace(xValue, yValue);// 10 15 passPrimitives(xValue, yValue); // 11 16 trace(xValue, yValue);// 10 15
Ve funkci passPrimitives() jsou hodnoty xParam a yParam zvýšeny, to však neovlivňuje hodnoty xValue a yValue, jak je znázorněno v posledním výrazu trace . To by bylo pravdivé v případě, že parametry byly pojmenovány shodně s proměnnými, xValue a yValue, protože xValue a yValue uvnitř funkce by ukazovaly do nového umístění v paměti, které existuje odděleně od proměnných stejného názvu vně funkce. Všechny ostatní objekty, tj. objekty nenáležící primitivním datovým typům, jsou vždy předány odkazem, což umožňuje změnit hodnotu původní proměnné. Například následující kód vytváří objekt pojmenovaný objVar se dvěma vlastnostmi, x a y. Objekt je předán jako argument funkci passByRef(). Protože objekt není primitivním typem, nejenom, že je předán jako odkaz, ale také tímto odkazem zůstane. To znamená, že změny provedené v parametrech uvnitř funkce ovlivní vlastnosti objektu vně funkce. function passByRef(objParam:Object):void { objParam.x++; objParam.y++; trace(objParam.x, objParam.y); } var objVar:Object = {x:10, y:15}; trace(objVar.x, objVar.y); // 10 15 passByRef(objVar); // 11 16 trace(objVar.x, objVar.y); // 11 16
Parametr objParam odkazuje na stejný objekt, jako globální proměnná objVar. Jak je možné vidět na příkazech trace v příkladu, změny vlastností x a y objektu objParam se odrazí v objektu objVar. Výchozí hodnoty parametru V jazyce ActionScript 3.0 lze pro funkci deklarovat výchozí hodnoty parametru. Pokud volání funkce s výchozími hodnotami parametrů vynechá parametr s výchozími hodnotami, použije se hodnota uvedená v definice funkce pro daný parametr. Všechny parametry s výchozími hodnotami musí být umístěny na konci seznamu parametrů. Hodnoty přiřazené jako výchozí hodnoty musí být konstanty z času kompilace. Existence výchozí hodnoty pro parametr efektivně činí tento parametr volitelným parametrem. Parametr bez výchozí hodnoty je považován za vyžadovaný parametr.
Poslední aktualizace 12.5.2011
80
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
Například následující kód vytváří funkci se třemi parametry, dva z nich mají výchozí hodnoty. Když je funkce volaná pouze jedním parametrem, použijí se pro parametry výchozí hodnoty. function defaultValues(x:int, y:int = 3, z:int = 5):void { trace(x, y, z); } defaultValues(1); // 1 3 5
Objekt arguments Když jsou funkci předány parametry, můžete použít objekt arguments pro přístup k informacím o parametrech předaných vaší funkci. Některé důležité aspekty objektu arguments zahrnují následující:
• Objekt arguments je polem, které zahrnuje všechny parametry předané funkci. • Vlastnost arguments.length hlásí počet parametrů předaných funkci. • Vlastnost arguments.callee poskytuje odkaz na samotnou funkci, což je užitečné pro rekurzivní volání výrazů funkce. Poznámka: Objekt arguments není dostupný v případě, že některý parametr je pojmenován arguments, nebo pokud použijete parametr ... (zbytek). Jestliže je objekt arguments odkazován v těle funkce, jazyk ActionScript 3.0 umožňuje, aby volání funkce zahrnovala více parametrů, než je definováno v definici funkce, ale v přísném režimu vygeneruje chybu kompilátoru, pokud počet parametrů neodpovídá počtu vyžadovaných parametrů (a volitelně i libovolných volitelných parametrů). Můžete použít aspekt pole objektu arguments a přistupovat k libovolnému parametru předanému funkci, bez ohledu na to, zda je funkce definovaná v definici funkce, nebo nikoliv. Následující příklad, který se kompiluje pouze ve standardním režimu, používá pole arguments společně s vlastností arguments.length ke sledování všech parametrů předaných funkci traceArgArray(): function traceArgArray(x:int):void { for (var i:uint = 0; i < arguments.length; i++) { trace(arguments[i]); } } traceArgArray(1, 2, 3); // // // //
output: 1 2 3
Vlastnost arguments.callee je často používána v anonymních funkcí pro vytvoření rekurze. Můžete ji používat ke zvýšení flexibility svého kódu. Pokud se název rekurzivní funkce změní v průběhu cyklu vývoje, nemusíte se starat o změnu rekurzivního volání ve své funkci, pokud použijete arguments.callee místo názvu funkce. Vlastnost arguments.callee se používá v následujícím výrazu funkce pro umožnění rekurze:
Poslední aktualizace 12.5.2011
81
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
var factorial:Function = function (x:uint) { if(x == 0) { return 1; } else { return (x * arguments.callee(x - 1)); } } trace(factorial(5)); // 120
Pokud ve své deklaraci funkce použijete parametr ... (zbytek), objekt arguments vám nebude dostupný. Místo toho je nutné přistupovat k parametrům pomocí názvů, které pro ně deklarujete. Rovněž je třeba dbát na to, aby se řetězec „arguments“ nepoužíval jako název parametru, protože stínuje objekt arguments. Pokud je například funkce traceArgArray()přepsána tak, aby byl přidán parametr arguments,
odkazy na arguments v těle funkce odkazují na parametr, spíše než na objekt arguments. Následující kód nevytváří žádný vstup: function traceArgArray(x:int, arguments:int):void { for (var i:uint = 0; i < arguments.length; i++) { trace(arguments[i]); } } traceArgArray(1, 2, 3); // no output
Objekt arguments v předchozí verzi jazyka ActionScript také obsahoval vlastnost pojmenovanou caller, která je odkazem na funkci volanou stávající funkcí. Vlastnost caller není v jazyce ActionScript 3.0 zastoupena, ale pokud potřebujete odkaz na volající funkci, můžete ji změnit tak, aby předala dodatečný parametr, který je odkazem na sebe samotný. Parametr ... (zbytek) Jazyk ActionScript 3.0 zavádí novou deklaraci parametru nazvanou parametr ... (zbytek). Tento parametr umožňuje specifikovat parametr pole, který přijímá jakýkoliv počet argumentů oddělených čárkou. Parametr může mít libovolný název, pokud se nejedná o vyhrazené slovo. Tato deklarace parametru musí být posledním specifikovaným parametrem. Při použití tohoto parametru není k dispozici objekt arguments. I když parametr ... (zbytek) poskytuje stejnou funkčnost, jako pole arguments a vlastnost arguments.length, neposkytuje funkčnost podobnou té, kterou nabízí arguments.callee. Měli byste zajistit, že nebudete muset použít arguments.callee před použitím parametru ... (zbytek). Následující příklad přepisuje funkci traceArgArray() pomocí parametru ... (zbytek) namísto objektu arguments:
Poslední aktualizace 12.5.2011
82
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
function traceArgArray(... args):void { for (var i:uint = 0; i < args.length; i++) { trace(args[i]); } } traceArgArray(1, 2, 3); // // // //
output: 1 2 3
Parametr ... (zbytek) může být také použit s ostatními parametry, pokud se jedná o poslední parametr v seznamu. Následující příklad modifikuje funkci traceArgArray() tak, aby její první parametr x byl typu int a druhý parametr používal parametr ... (zbytek). Výstup vynechává první hodnotu, protože první parametr již není součástí pole vytvořeného parametrem ... (zbytek). function traceArgArray(x: int, ... args) { for (var i:uint = 0; i < args.length; i++) { trace(args[i]); } } traceArgArray(1, 2, 3); // output: // 2 // 3
Funkce jako objekty Funkce v jazyce ActionScript 3.0 jsou objekty. Když vytvoříte funkci, vytváříte objekt, který nejen že může být předán jako parametr do jiné funkce, ale také k sobě může mít připojeny vlastnosti a metody. Funkce předané jako argumenty jiné funkci jsou předány formou odkazu a nikoliv hodnotou. Když předáte funkci jako argument, použijete pouze identifikátor a nikoliv operátor závorky, který používáte k zavolání metody. Například následující kód předává funkci pojmenovanou clickListener() jako argument metody addEventListener(): addEventListener(MouseEvent.CLICK, clickListener);
I když se to může zdát novým programátorům jazyka ActionScript podivné, funkce mohou mít vlastnosti a metody, stejně jako kterékoliv ostatní objekty. Ve skutečnosti každá funkce má vlastnost pouze ke čtení, pojmenovanou length, která ukládá několik parametrů definovaných pro funkci. To je odlišné od vlastnosti arguments.length, která hlásí počet argumentů odeslaných funkci. Vzpomeňte si, že v jazyce ActionScript počet argumentů odeslaných funkci může překročit počet parametrů definovaných pro tuto funkci. Následující příklad, který se kompiluje pouze ve standardním režimu, protože přísný režim vyžaduje přesnou shodu mezi počtem předaných argumentů a počtem argumentů definovaných, zobrazuje rozdíl mezi dvěma vlastnostmi:
Poslední aktualizace 12.5.2011
83
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
// Compiles only in standard mode function traceLength(x:uint, y:uint):void { trace("arguments received: " + arguments.length); trace("arguments expected: " + traceLength.length); } traceLength(3, 5, 7, 11); /* output: arguments received: 4 arguments expected: 2 */
Ve standardním režimu lze definovat vlastní vlastnosti funkce jejich nadefinováním vně těla funkce. Vlastnosti funkce mohou sloužit jako kvazi-statické vlastnosti, umožňující uložit stav proměnné, související s funkcí. Například můžete chtít sledovat počet volání specifické funkce. Taková funkce může být užitečná v případě, že píšete hru a chcete sledovat počet použití specifického příkazu uživatelem, i když proto můžete také použít vlastnost třídy static. Následující příklad, který se kompiluje pouze ve standardním režimu, protože přísný režim neumožňuje přidávat k funkci dynamické vlastnosti, vytváří vlastnost funkce mimo deklarování funkce a zajišťuje zvýšení hodnoty vlastnosti při každém zavolání funkce: // Compiles only in standard mode var someFunction:Function = function ():void { someFunction.counter++; } someFunction.counter = 0; someFunction(); someFunction(); trace(someFunction.counter); // 2
Rozsah funkce Rozsah funkce stanoví nejenom to, kde může být program zavolán, ale také k jakým definicím může funkce přistupovat. Stejný rozsah pravidel, který platí pro identifikátory proměnné, platí také pro identifikátory funkce. Funkce deklarované v globálním rozsahu je přístupná prostřednictvím vašeho kódu. Například jazyk ActionScript 3.0 obsahuje globální funkce, například isNaN() a parseInt(), které jsou dostupné kdekoliv ve vašem kódu. Vnořená funkce - funkce deklarovaná v jiné funkci - může být použita kdekoliv ve funkci, ve které byla deklarovaná. Řetěz rozsahu Při každém spuštění vykonávání funkce je vytvořeno několik objektů a vlastností. Za prvé je vytvořen speciální objekt nazvaný aktivační objekt, který uloží parametr a všechny místní proměnné nebo funkce deklarované v těle funkce. Nemůžete přistupovat k objektu aktivace přímo, protože se jedná i interní mechanismu. Za druhé je vytvořen řetězec rozsahu, který obsahuje uspořádaný seznam objektů, u nichž běhový modul kontroluje, zda obsahují deklarace identifikátoru. Každá funkce, která je spouštěna, má řetěz rozsahu, který je uložen ve vnitřní vlastnosti. Pro vnořené funkce řetěz rozsahu začíná vlastní aktivací objektu, následovanou aktivačním objektem nadřazené funkce. Řetěz pokračuje tímto způsobem, dokud nedosáhne globálního objektu. Spustí se globální objekt, který je vytvořen v programu v jazyce ActionScript, a obsahuje všechny globální proměnné a funkce.
Poslední aktualizace 12.5.2011
84
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Jazyk ActionScript a jeho syntaxe
Uzavřené funkce Uzavřená funkce je objektem, který obsahuje snímek funkce a jeho lexikální prostředí. Lexikální prostředí funkce zahrnuje všechny proměnné, vlastnosti, metody a objekty v řetězu rozsahu funkce, společně s jejich hodnotami. Uzavřené funkce jsou vytvořeny vždy při vykonání funkce, odloučeně od objektu nebo třídy. Skutečnost, že uzavřené funkce si uchovávají rozsah, ve kterém byly definovány, vytváří zajímavé výsledky, když je funkce předána jako argument nebo vrací hodnotu jinému rozsahu. Například následující kód vytváří dvě funkce: foo(), která vrací vnořenou funkci pojmenovanou rectArea(), která vypočítává plochu trojúhelníku a funkci bar(), která volá foo() a ukládá vrácenou uzavřenou funkci do proměnné nazvané myProduct. I když funkce bar() definuje vlastní místní proměnnou x (s hodnotou 2), když je zavolána uzavřená funkce myProduct(), uchovává proměnnou x (s hodnotou 40) definovanou ve funkci foo(). Funkce bar() proto vrací hodnotu 160 místo 8. function foo():Function { var x:int = 40; function rectArea(y:int):int // function closure defined { return x * y } return rectArea; } function bar():void { var x:int = 2; var y:int = 4; var myProduct:Function = foo(); trace(myProduct(4)); // function closure called } bar(); // 160
Metody se chovají podobně v tom, že si uchovávají informace o lexikálním prostředí, ve kterém byly vytvořeny. Tato charakteristika je nejznatelnější v případě, že metoda je extrahována ze své instance, což vytvoří vázanou metodu. Hlavní rozdíl mezi uzavřenou funkcí a vázanou metodou je v tom, že hodnota klíčového slova this ve vázané metodě vždy odkazuje na instanci, ke které byla původně připojena, zatímco v uzavřené funkci se hodnota klíčového slova this může měnit.
Poslední aktualizace 12.5.2011
85
Kapitola 4: Objektově orientované programování v jazyce ActionScript Úvod k objektově orientovanému programování Objektově orientované programování je způsob organizování kódu v programu jeho seskupením do objektů. Výraz objekt v tomto významu znamená samostatný element, který zahrnuje informace (datové hodnoty) a funkce. Při objektově orientovaném přístupu k organizování programu se seskupují určité kusy informací spolu s běžnými funkcemi nebo akcemi spojenými s danou informací. Lze například seskupit informace o hudbě, např. název alba, název skladby či jméno interpreta, s funkcí jako „přidat skladbu do seznamu skladeb“ nebo „přehrát všechny skladby tohoto interpreta“. Tyto kusy informací se zkombinují do jediné položky, a to do objektu (například „Album” nebo „MusicTrack”). Sbalení hodnot a funkcí dohromady poskytuje celou řadu výhod. K hlavním výhodám patří především to, že místo několika proměnných stačí použít jen jednu. Kromě toho tento systém uchovává příbuzné funkce pohromadě. A konečně díky kombinování informací a funkcí lze strukturovat programy způsobem, který lépe odpovídá skutečnosti.
Třídy Třída je abstraktní reprezentací objektu. Třída uchovává informace o typech dat, které objekt může mít a o chování, které může objekt vykazovat. Užitečnost této abstrakce nemusí být zřejmá při psaní malých skriptů, jež obsahují pouze několik navzájem reagujících objektů. Nicméně s rostoucím rozsahem programu vzrůstá i počet objektů, které je třeba spravovat. V takovém případě lze pomocí tříd lépe řídit, jakým způsobem se budou objekty vytvářet a jak budou navzájem reagovat. Již od jazyka ActionScript 1.0 mohli programátoři využívající jazyk ActionScript použít objekty funkce pro vytvoření konstruktů, které se podobaly třídám. Jazyk ActionScript 2.0 přidal formální podporu tříd pomocí klíčových slov, například class a extends. Verze jazyka ActionScript 3.0 nejen že nadále podporuje klíčová slova zavedená ve verzi ActionScript 2.0, ale také přidává nové schopnosti. Jazyk ActionScript 3.0 například zahrnuje lepší řízení přístupu s atributy protected a internal. Také poskytuje lepší kontrolu nad přebíráním vlastností pomocí klíčových slov final a override. Vývojářům, kteří již vytvářeli třídy například v programovacích jazycích Java, C++ nebo C#, poskytuje jazyk ActionScript podobné prostředí. Jazyk ActionScript používá řadu stejných klíčových slov a názvů atributů, např. class, extends a public. Poznámka: V dokumentaci jazyka Adobe ActionScript označuje pojem vlastnost jakýkoliv člen objektu nebo třídy, včetně proměnných, konstant a metod. Dále ačkoliv jsou pojmy třída a statický často navzájem zaměňovány, zde se liší. Například fráze „vlastnosti třídy“ se vztahuje na všechny členy třídy, nikoliv pouze na statické členy.
Definice třídy Definice třídy jazyka ActionScript 3.0 používají syntaxi, která je podobná syntaxi používané v definici tříd jazyka ActionScript 2.0. Správná syntaxe pro definici třídy vyvolá klíčové slovo class následované názvem třídy. Za názvem třídy následuje tělo třídy, které je obklopeno složenými závorkami ({}). Například následující kód vytvoří třídu pojmenovanou Shape, která obsahuje jednu proměnnou pojmenovanou visible:
Poslední aktualizace 12.5.2011
86
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Objektově orientované programování v jazyce ActionScript
public class Shape { var visible:Boolean = true; }
Jedna důležitá změna syntaxe zahrnuje definice třídy, které jsou uvnitř balíku. Jestliže je v jazyce ActionScript 2.0 třída uvnitř balíku, musí být název balíku obsažen v deklaraci třídy. V jazyce ActionScript 3.0, který zahrnuje příkaz package, musí být název balíku zahrnut do deklarace balíku namísto zahrnutí v deklaraci třídy. Například následující deklarace třídy ukazuje, jak je třída BitmapData, která je součástí balíku flash.display, definována v jazycích ActionScript 2.0 a ActionScript 3.0: // ActionScript 2.0 class flash.display.BitmapData {} // ActionScript 3.0 package flash.display { public class BitmapData {} }
Atributy třídy Jazyk ActionScript 3.0 vám umožňuje úpravu definicí třídy pomocí jednoho z následujících čtyř atributů: Atribut
Definice
dynamic
Umožňuje přidávání vlastností k instancím v čase zpracování.
final
Nesmí být rozšířeno jinou třídou.
internal (výchozí)
Viditelné pro reference uvnitř aktuálního balíku.
public
Viditelné pro odkazy kdekoliv.
Každý z těchto atributů, s výjimkou atributu internal, je nutné pro získání přiřazeného chování výslovně zahrnout. Pokud například při definování třídy nezahrnete atribut dynamic, nebude možné do instance třídy přidávat za běhu vlastnosti. Atribut výslovně přiřadíte jeho umístěním na začátek definice třídy, dle příkladu v následujícím kódu: dynamic class Shape {}
Všimněte si, že seznam nezahrnuje atribut nazvaný abstract. Abstraktní třídy nejsou v jazyce ActionScript 3.0 podporovány. Všimněte si také, že seznam nezahrnuje atributy pojmenované private a protected. Tyto atributy mají význam pouze uvnitř definice třídy a nelze je použít na samotné třídy. Jestliže nechcete, aby byla třída mimo balík veřejně viditelná, umístěte jí dovnitř balíku a označte třídu atributem internal. Případně můžete vypustit atribut internal i public a kompilátor přidá atribut internal automaticky. Rovněž lze definovat třídu tak, aby byla viditelná pouze ve zdrojovém souboru, ve kterém je definována. Umístěte třídu na konec zdrojového souboru pod koncovou složenou závorku definice balíku. Tělo třídy Tělo třídy je obklopeno složenými závorkami. Definuje proměnné, konstanty a metody dané třídy. Následující příklad znázorňuje deklaraci pro třídu Usnadnění přístupu v jazyce ActionScript 3.0: public final class Accessibility { public static function get active():Boolean; public static function updateProperties():void; }
Poslední aktualizace 12.5.2011
87
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Objektově orientované programování v jazyce ActionScript
Jmenný prostor můžete definovat také uvnitř těla třídy. Následující příklad ukazuje, jak lze definovat jmenný prostor v těle třídy, a jak je použít jako atribut metody v dané třídě: public class SampleClass { public namespace sampleNamespace; sampleNamespace function doSomething():void; }
Jazyk ActionScript 3.0 vám umožňuje do těla třídy zahrnout nejen definice, ale také příkazy. Příkazy, které jsou umístěny uvnitř těla třídy, ale vně definice metody, budou provedeny přesně jednou. K jejich provedení dojde při prvním nalezení definice třídy a vytvoření přidruženého objektu třídy. Následující příklad zahrnuje volání externí funkce hello()a příkaz trace, který vytvoří hlášení o potvrzení při definování třídy: function hello():String { trace("hola"); } class SampleClass { hello(); trace("class created"); } // output when class is created hola class created
V jazyce ActionScript 3.0 je povoleno definovat statickou vlastnost a vlastnost instance se stejným názvem v těle stejné třídy. Například následující kód deklaruje statickou proměnnou nazvanou message a proměnnou instance stejného názvu: class StaticTest { static var message:String = "static variable"; var message:String = "instance variable"; } // In your script var myST:StaticTest = new StaticTest(); trace(StaticTest.message); // output: static variable trace(myST.message); // output: instance variable
Atributy vlastnosti třídy Mluvíme-li o modelu objektu jazyka ActionScript, pojem vlastnost znamená cokoliv, co může být členem třídy, včetně proměnných, konstant a metod. Nicméně v Referenční příručce jazyka Adobe ActionScript 3.0 pro řešení Adobe Flash Platform se tento pojem používá v užším významu. V tomto kontextu se pojem vlastnost vztahuje pouze k členům třídy, jež jsou proměnnou, nebo jsou definovány metodou pro získání nebo pro nastavení. V jazyce ActionScript 3.0 existuje množina atributů, které lze použít s jakoukoliv vlastností třídy. Následující tabulka uvádí tuto množinu atributů. Atribut
Definice
internal (výchozí)
Viditelné pro odkazy uvnitř stejného balíku.
private
Viditelné pro odkazy ve stejné třídě.
protected
Viditelné pro odkazy ve stejné a v odvozených třídách.
Poslední aktualizace 12.5.2011
88
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Objektově orientované programování v jazyce ActionScript
Atribut
Definice
public
Viditelné pro odkazy kdekoliv.
static
Narozdíl od instancí třídy určuje, že vlastnost patří do příslušné třídy.
UserDefinedNamespace
Název vlastního jmenného prostoru definovaného uživatelem.
Atributy jmenného prostoru pro ovládání přístupu Jazyk ActionScript 3.0 nabízí čtyři speciální atributy, které ovládají přístup k vlastnostem definovaných uvnitř třídy: public, private, protected a internal. Atribut public zviditelní vlastnost kdekoliv ve vašem skriptu. Například pro to, aby byla metoda dostupná pro kód mimo svůj balík, musíte deklarovat metodu s atributem public. To platí pro jakoukoliv vlastnost, ať už je deklarována pomocí klíčových slov var, const nebo function. Atribut private zviditelní vlastnost pouze pro volání v rámci třídy definující danou vlastnost. Toto chování se odlišuje od chování atributu private v jazyce ActionScript 2.0, který umožňoval přístup podtřídy k soukromé vlastnosti v nadřazené třídě. Další důležitá změna v chování se týká přístupu v čase zpracování. V jazyce ActionScript 2.0 klíčové slovo private zakazovalo přístup pouze v čase sestavování a v čase zpracování jej šlo snadno obejít. V jazyce ActionScript 3.0 toto již neplatí. Vlastnosti označené jako private jsou nedostupné v čase kompilace i v čase zpracování. Například následující kód vytvoří jednoduchou třídu pojmenovanou PrivateExample s jednou soukromou proměnnou a poté se pokusí o přístup k soukromé proměnné z vnějšku třídy. class PrivateExample { private var privVar:String = "private variable"; } var myExample:PrivateExample = new PrivateExample(); trace(myExample.privVar);// compile-time error in strict mode trace(myExample["privVar"]); // ActionScript 2.0 allows access, but in ActionScript 3.0, this is a run-time error.
V jazyce ActionScript 3.0 má pokus o přístup k soukromé vlastnosti pomocí operátoru tečky (myExample.privVar) v případě použití přísného režimu za následek chybu v čase kompilace. V jiném případě je chyba nahlášena v čase zpracování, stejně jako při použití operátoru pro přístup k vlastnosti (myExample["privVar"]). Následující tabulka uvádí přehled výsledku přístupu k soukromé vlastnosti, která náleží k uzavřené (nikoliv dynamické ) třídě: Přísný režim
Standardní režim
operátor tečky (.)
chyba v čase kompilace
chyba v čase zpracování
operátor závorky ([])
chyba v čase zpracování
chyba v čase zpracování
Ve třídách deklarovaných s atributem dynamic nebudou mít pokusy o přístup k soukromé proměnné za následek chybu v době běhu. Místo toho nebude proměnná viditelná, takže bude vrácena hodnota nedefinováno. K chybě v čase kompilace nicméně dojde, pokud používáte operátor tečky v přísném režimu. Následující příklad je stejný jako předcházející příklad, pouze s výjimkou, že třída PrivateExample je deklarována jako dynamická:
Poslední aktualizace 12.5.2011
89
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Objektově orientované programování v jazyce ActionScript
dynamic class PrivateExample { private var privVar:String = "private variable"; } var myExample:PrivateExample = new PrivateExample(); trace(myExample.privVar);// compile-time error in strict mode trace(myExample["privVar"]); // output: undefined
Dynamické třídy obecně vrací hodnotu undefined namísto vygenerování chyby v případě, kdy se kód externí ke třídě pokouší o přístup k soukromé vlastnosti. Následující tabulka ukazuje, že chyba je vygenerována pouze tehdy, je-li operátor tečky používán pro přístup k soukromé vlastnosti v přísném režimu. Přísný režim
Standardní režim
operátor tečky (.)
chyba v čase kompilace
undefined
operátor závorky ([])
undefined
undefined
Atribut protected, který je v jazyce ActionScript 3.0 nový, zviditelní vlastnost pro volající v rámci vlastní třídy nebo podtřídy. Jinými slovy, chráněná vlastnost je dostupná v rámci vlastní třídy nebo pro třídy, které leží kdekoliv pod ní v hierarchii dědičnosti. To je pravdivé pro podtřídu ve stejném i v odlišném balíku. Pro ty, kdo jsou obeznámeni s jazykem ActionScript 2.0, je tato funkce podobná jako atribut private v jazyce ActionScript 2.0. Atribut protected jazyka ActionScript 3.0 se rovně podobá atributu protected v jazyce Java. Liší se v tom, že verze v jazyce Java rovněž povoluje přístup k volajícím v rámci stejného balíku. Atribut protected je užitečný, jestliže máte proměnnou nebo metodu, kterou vaše podtřídy potřebují skrýt z kódu mimo řetězec dědičnosti. Atribut internal, který je v jazyce ActionScript 3.0 nový, zviditelní vlastnost pro volající v rámci svého vlastního balíku. Jedná se o výchozí atribut pro kód uvnitř balíku a použije se na jakoukoliv vlastnost, která nemá žádný z následujících atributů:
•
public
•
private
•
protected
• uživatelem definovaný jmenný prostor Atribut internal je podobný výchozímu ovládání přístupu v aplikaci Java, ačkoliv v Javě není pro tuto úroveň přístupu žádný explicitní název a lze jej dosáhnou pouze prostřednictvím vynechání žádného jiného modifikátoru přístupu. Atribut internal je dostupný v jazyce ActionScript 3.0 a umožňuje vám výslovně zvýraznit váš záměr zviditelnění vlastnosti pouze pro volající v rámci vlastního balíku.
Atribut static Atribut static, který lze použít s vlastnostmi deklarovanými pomocí klíčových slov var, const nebo function, vám umožňuje přiřadit vlastnost ke třídě, spíše než k instancím dané třídy. Kód mimo danou třídu musí vyvolat statické vlastnosti pomocí názvu třídy namísto názvu instance. Statické vlastnosti nejsou zděděny podtřídami, ale dané vlastnosti jsou součástí řetězce rozsahu podtřídy. To znamená, že v rámci těla podtřídy lze statickou proměnnou nebo metodu použít bez odkazu na třídu, ve které byla definována.
Atributy jmenného prostoru definované uživatelem Jako alternativu k předdefinovaným atributům ovládání přístupu můžete vytvořit vlastní jmenný prostor, který bude použit jako atribut. Na každou definici může být použit pouze jeden atribut oboru názvů a takový atribut nemůže být použit v kombinaci s jakýmikoliv atributy ovládání přístupu (public, private, protected, internal).
Poslední aktualizace 12.5.2011
90
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Objektově orientované programování v jazyce ActionScript
Proměnné Proměnné mohou být deklarovány buď pomocí klíčového slova var nebo const. U proměnných deklarovaných pomocí klíčového slova var lze jejich hodnoty několikrát změnit, a to kdykoliv při provádění skriptu. Proměnné deklarované pomocí klíčového slova const jsou vyvolané konstanty a hodnoty k nim můžete přiřadit pouze jednou. Pokus o přiřazení nové hodnoty ke konkretizované konstantě vyvolá chybu. Statické proměnné Statické proměnné jsou deklarovány pomocí kombinace klíčového slova static a buďto příkazem var nebo const. Statické proměnné, které jsou připojeny ke třídě spíše než k instanci třídy, jsou používány pro ukládání a sdílení informací používaných na celou třídu objektů. Statická proměnná je například vhodná, jestliže si přejete zachovat čítač toho, kolikrát je třída konkretizovaná, nebo jestliže si přejete uchovat maximální počet instancí tříd, které jsou povoleny. Následující příklad vytváří proměnnou totalCount, která bude sledovat počet konkretizací třídy a konstantu MAX_NUM pro uchování maximálního počtu konkretizací. Proměnné totalCount a MAX_NUM jsou statické, protože obsahují hodnoty, které se vztahují ke třídě jako celku, spíše než k určité instanci. class StaticVars { public static var totalCount:int = 0; public static const MAX_NUM:uint = 16; }
Kód, který je externí ke třídě StaticVars a jakékoliv z jejích podtříd, může odkazovat vlastnosti totalCount a MAX_NUM pouze prostřednictvím samotné třídy. Správný je například následující kód: trace(StaticVars.totalCount); // output: 0 trace(StaticVars.MAX_NUM); // output: 16
Ke statickým proměnným nemáte přístup prostřednictvím instance třídy, takže následující kód vrátí chyby: var myStaticVars:StaticVars = new StaticVars(); trace(myStaticVars.totalCount); // error trace(myStaticVars.MAX_NUM); // error
Proměnné, které jsou deklarovány pomocí klíčového slova static i const, musí být iniciovány v čase deklarace konstanty, jako to třída StaticVars provádí pro MAX_NUM. K MAX_NUM uvnitř konstruktoru nebo metody instance nemůžete přiřadit hodnotu. Následující kód generuje chybu, protože se nejedná o platný způsob inicializace statické konstanty: // !! Error to initialize static constant this way class StaticVars2 { public static const UNIQUESORT:uint; function initializeStatic():void { UNIQUESORT = 16; } }
Proměnné instance: Proměnné instance zahrnují vlastnosti deklarované pomocí klíčových slov var a const, ale bez klíčového slova static. Proměnné instance připojené k instancím třídy spíše než k celé třídě jsou užitečné pro uchovávání hodnot, které jsou specifické pro instanci. Například třída Array má vlastnost instance pojmenovanou length uchovávající počet prvků pole, které vlastní určitá instance třídy Array.
Poslední aktualizace 12.5.2011
91
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Objektově orientované programování v jazyce ActionScript
Proměnné instance, ať už deklarovány jako var nebo const, nemohou být potlačeny v podtřídě. Funkce podobné potlačení proměnných můžete nicméně dosáhnout potlačením metod mechanismů získání a nastavení.
Metody Metody jsou funkce, které jsou součástí definice třídy. Po vytvoření instance třídy je k dané instanci připojena metoda. Narozdíl od funkce deklarované mimo třídu nelze metodu použít mimo instance, ke které byla připojena. Metody jsou definovány pomocí klíčového slova function. Jako u každé vlastnosti třídy lze na metody aplikovat jakékoliv atributy této vlastnosti třídy, včetně atributů „private“, „protected“, „public“, „internal“, „static“ nebo „custom namespace“. Můžete použít například následující příkaz funkce: public function sampleFunction():String {}
Nebo můžete použít proměnnou, ke které připojíte výraz funkce, a to následovně: public var sampleFunction:Function = function () {}
Ve většině případů použijete z následujících důvodů příkaz funkce namísto výrazu funkce:
• Příkazy funkce jsou stručnější a snadněji se čtou. • Příkazy funkce vám umožňují použít klíčová slova override a final. • Příkazy funkce vytvářejí pevnější vazbu mezi identifikátorem (název funkce) a kódem uvnitř těla metody. Protože hodnota proměnné může být změněna pomocí příkazu přiřazení, může být spojení mezi proměnnou a výrazem její funkce kdykoliv přerušeno. Ačkoliv se tomuto problému můžete vyhnout deklarováním proměnné pomocí const namísto var, tato technika není považována za nejlepší postup, neboť znesnadňuje čtení kódu a brání použití klíčových slov override a final. Jedním případem, kdy musíte použít výraz funkce, je situace, kdy si přejete připojit funkci k objektu prototypu.
Metody konstruktoru Metody konstruktoru, někdy nazývané konstruktory, jsou funkce, které sdílejí stejný název jako třídy, ve kterých jsou definovány. Každý kód, který zahrnete do metody konstruktoru je proveden, kdykoliv je instance dané třídy vytvořena pomocí klíčového slova new. Následující kód například definuje jedinou třídu nazvanou Example, která obsahuje jedinou vlastnost pojmenovanou status. Počáteční hodnota proměnné status je množina uvnitř funkce konstruktoru. class Example { public var status:String; public function Example() { status = "initialized"; } } var myExample:Example = new Example(); trace(myExample.status); // output: initialized
Metody konstruktoru mohou být pouze veřejné, ale použití atributu public je volitelné. Na konstruktoru nemůžete použít žádný z jiných specifikátorů přístupu, včetně private, protected nebointernal. S metodou konstruktoru také nemůžete použít uživatelem definovaný jmenný prostor.
Poslední aktualizace 12.5.2011
92
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Objektově orientované programování v jazyce ActionScript
Konstruktor může provést explicitní volání ke konstruktoru své přímé nadřazené třídy pomocí příkazu super(). Jestliže konstruktor nadřazené třídy není explicitně vyvolán, kompilátor automaticky vloží volání před první příkaz do těla konstruktoru. Metody nadřazené třídy můžete také vyvolat pomocí předpony super jako odkazu na nadřazenou třídu. Jestliže se rozhodnete použít super() i super v těle stejného konstruktoru, volejte nejprve super(). V opačném případě se odkaz super nebude chovat dle očekávání. Konstruktor super() by měl být také vyvolán před příkazem throw nebo return. Následující příklad demonstruje, co se stane, jestli se pokusíte použít odkaz super před vyvoláním konstruktoru super(). Nová třída ExampleEx rozšiřuje třídu Example. Konstruktor ExampleEx se pokusí o přístup k proměnné stavu definované ve své nadřazené třídě, ale tento pokus provede před vyvoláním super(). Příkaz trace() uvnitř konstruktoru ExampleEx vytvoří hodnotu null, protože proměnná status není dostupná, dokud není konstruktor super() proveden. class ExampleEx extends Example { public function ExampleEx() { trace(super.status); super(); } } var mySample:ExampleEx = new ExampleEx(); // output: null
Ačkoliv je uvnitř konstruktoru povoleno použít příkaz return, není povoleno vrátit hodnotu. Jinými slovy, příkazy return nesmí mít přiřazené výrazy nebo hodnoty. Následně pak metodám konstruktoru není povoleno vracet hodnoty, což znamená, že nelze specifikovat žádný typ návratu. Jestliže v dané třídě nedefinujete metodu konstruktoru, kompilátor automaticky vytvoří prázdný konstruktor. Pokud daná třída rozšiřuje jinou třídu, kompilátor zahrne do konstruktoru, kterého vytvoří, volání metody super().
Statické metody Statické metody, označované také metody třídy , jsou metody deklarované pomocí klíčového slova static. Statické metody, které jsou připojeny ke třídě spíše než k instanci třídy, jsou užitečné pro funkci zapouzdření, která ovlivňuje něco jiného než stav jednotlivé instance. Protože jsou statické metody přiřazeny ke třídě jako celek, jsou přístupné pouze prostřednictvím třídy, ale nikoliv prostřednictvím instance třídy. Statické metody jsou užitečné pro funkci zapouzdření, která neovlivňuje pouze stav instancí třídy. Jinými slovy, metoda by měla být statická, jestliže poskytuje funkčnost, která přímo neovlivňuje hodnotu instance třídy. Například třída Date má statickou metodu pojmenovanou parse(), která přebírá řetězec a převádí jej na číslo. Metoda je statická, protože neovlivňuje jednotlivé instance třídy. Místo toho metoda parse() převezme řetězec, který představuje hodnotu dat, analyzuje jej a vrátí několik formátů kompatibilních s interní reprezentací objektu Date. Tato metoda není metoda instance, protože použití dané metody pro instanci třídy Date nedává smysl. Porovnejte statickou metodu parse() s jednou z metod instance třídy Date, například s metodou getMonth(). Metoda getMonth() je metoda instance, protože operuje přímo na hodnotě instance, a to dosazením určité komponenty (měsíce) instance Date. Protože statické metody nejsou svázány s jednotlivými instancemi, nemůžete použít klíčová slova this nebo super v rámci těla statické metody. Reference this i reference super mají význam pouze v rámci daného kontextu metody instance. V kontrastu k některým jiným programovacím jazykům založeným na třídě nejsou statické metody v jazyce ActionScript 3.0 zděděné.
Poslední aktualizace 12.5.2011
93
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Objektově orientované programování v jazyce ActionScript
Metody instance Metody instance jsou metody, které jsou prohlášeny bez klíčového slova static. Metody instance, které jsou připojeny k instancím třídy namísto třídy jako celku, jsou užitečné pro implementaci funkčnosti, která ovlivňuje jednotlivé instance třídy. Například třídy Array obsahuje metodu instance pojmenovanou sort(), která operuje přímo na instancích Array. V rámci těla metody instance jsou jak statické tak proměnné instance v rozsahu, což znamená, že proměnné definované ve stejné třídě mohou být odkazovány pomocí jednoho identifikátoru. Například následující třída CustomArray rozšiřuje třídu Array. Třída CustomArray definuje statickou proměnnou pojmenovanou arrayCountTotal pro sledování celkového počtu instancí tříd, instanci pojmenovanou arrayNumber, která sleduje pořadí, ve kterém jsou instance vytvářeny a metodu instance pojmenovanou getPosition(), která vrátí hodnoty těchto proměnných. public class CustomArray extends Array { public static var arrayCountTotal:int = 0; public var arrayNumber:int; public function CustomArray() { arrayNumber = ++arrayCountTotal; } public function getArrayPosition():String { return ("Array " + arrayNumber + " of " + arrayCountTotal); } }
Ačkoliv kód, který je umístěn mimo třídu, musí přistupovat ke statické proměnné arrayCountTotal přes objekt třídy pomocí vlastnosti CustomArray.arrayCountTotal, kód umístěný uvnitř těla metody getPosition() může přímo odkazovat ke statické proměnné arrayCountTotal. Toto je pravda dokonce pro statické proměnné v nadřazených třídách. Ačkoliv statické vlastnosti nejsou zděděny v jazyce ActionScript 3.0, statické vlastnosti v nadřazené třídě jsou v rozsahu. Například třída Array má několik málo statických proměnných. Jednou z nich je konstanta pojmenovaná DESCENDING. Kód v nadřazené třídě může dosáhnout přístupu ke statické konstantě DESCENDING pomocí jednoduchého identifikátoru: public class CustomArray extends Array { public function testStatic():void { trace(DESCENDING); // output: 2 } }
Hodnota reference this uvnitř těla metody instance je odkazem na instanci, ke které je metoda připojena. Následující kód ukazuje, že odkaz this ukazuje k instanci, která obsahuje danou metodu:
Poslední aktualizace 12.5.2011
94
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Objektově orientované programování v jazyce ActionScript
class ThisTest { function thisValue():ThisTest { return this; } } var myTest:ThisTest = new ThisTest(); trace(myTest.thisValue() == myTest); // output: true
Dědičnost metody instance lze ovládat pomocí klíčových slov override a final. Atribut override můžete použít pro novou definici zděděné metody a atribut final zabraňuje podtřídám v potlačení metody.
Získání a nastavení metod mechanismů přístupu Funkce získání a nastavení mechanismů přístupu se nazývají mechanismy získání a mechanismy nastavení. Umožňují vám zachovat programovací principy skrývání informací a zapouzdření a pro vámi vytvářené třídy poskytují snadno použitelné programovací rozhraní. Funkce získání a nastavení vám umožňují zachovat vlastnosti vaší třídy pouze pro danou třídu, ale umožňují uživatelům vaší třídy přístup k těmto vlastnostem, jako v případě přístupu k proměnné třídy namísto vyvolání metody třídy. Výhodou tohoto přístupu je to, že vám umožňuje vyhnout se tradičním funkcím přístupových mechanismů s nepraktickými jmény, například getPropertyName() a setPropertyName(). Další výhodou mechanismů získání a nastavení je to, že pro každou vlastnost nemusíte mít dvě veřejné funkce, které umožňují čtení a zápis. Následující příklad třídy pojmenovaný GetSet zahrnuje funkce získání a nastavení mechanismů přístupu pojmenované publicAccess(), které poskytují přístup k soukromé proměnné pojmenované privateProperty: class GetSet { private var privateProperty:String; public function get publicAccess():String { return privateProperty; } public function set publicAccess(setValue:String):void { privateProperty = setValue; } }
Při pokusu o přímý přístup k vlastnosti privateProperty dojde k chybě: var myGetSet:GetSet = new GetSet(); trace(myGetSet.privateProperty); // error occurs
Namísto toho uživatel třídy GetSet použije něco, co se jeví jako vlastnost pojmenovaná publicAccess, ale ve skutečnosti se jedná o dvojici funkcí získání a nastavení mechanismu přístupu, které operují na soukromé vlastnosti s názvem privateProperty. Následující příkaz konkretizuje třídu GetSet a poté nastaví hodnotu privateProperty pomocí veřejného mechanismu přístupu s názvem publicAccess: var myGetSet:GetSet = new GetSet(); trace(myGetSet.publicAccess); // output: null myGetSet.publicAccess = "hello"; trace(myGetSet.publicAccess); // output: hello
Poslední aktualizace 12.5.2011
95
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Objektově orientované programování v jazyce ActionScript
Funkce mechanismů získání a nastavení také umožňují potlačení vlastností, které jsou zděděny z nadřazené třídy. To není možné při použití běžných proměnných členů tříd. Proměnné členů třídy, které jsou deklarovány pomocí klíčového slova var nelze v podtřídě potlačit. Vlastnosti vytvořené pomocí funkcí mechanismů získání a nastavení toto omezení nicméně nemají. Atribut override můžete použít na funkcích mechanismů získání a nastavení, které jsou zděděny z nadřazené třídy.
Metody vazeb Metoda vazby, někdy nazvaná metoda ohraničení, je jednoduše metoda vyjmutá ze své instance. Příklady metod vazby zahrnují metody, které jsou předány jako argumenty funkci nebo navráceny jako hodnoty z funkce. Nově v jazyce ActionScript 3.0 je metoda vazby podobná metodě ohraničení v tom, že zachovává své lexikální prostředí i v případě, že je vyjmuta ze své instance. Klíčovým rozdílem mezi metodou vazby a funkcí ohraničení je nicméně to, že reference this pro metodu vazby zůstává propojena s instancí, která danou metodu implementuje. Jinými slovy reference this v metodě vazby vždy poukazuje na původní objekt, který danou metodu implementoval. Pro funkci ohraničení je reference this generická, což znamená, že ukazuje na jakýkoliv objekt, ke kterému je funkce v době svého volání připojena. Jestliže používáte klíčové slovo this, je důležité, abyste porozuměli metodám vazeb. Vzpomeňte si, že klíčové slovo this poskytuje odkaz na nadřazený objekt metody. Většina programátorů jazyka ActionScript očekává, že klíčové slovo this vždy odkazuje na objekt nebo třídu obsahující definici metody. Bez provázání metod by toto nicméně neplatilo vždy. V předchozích verzích jazyka ActionScript například reference this neodkazovala vždy k instanci, která danou metodu implementovala. Při vyjmutí metod z instance v jazyce ActionScript 2.0 je reference this nejen nepropojena s původní instancí, ale ani proměnné členů a metody třídy instance nejsou dostupné. To v jazyce ActionScript 3.0 nepředstavuje problém, protože metody provázání jsou automaticky vytvořeny při odeslání metody jako parametru. Metody vazeb zajišťují, že klíčové slovo this vždy odkazuje na objekt nebo třídu, ve které je definována metoda. Následující kód definuje třídu pojmenovanou ThisTest, která obsahuje metodu s názvem foo() definující metodu vazby a metodu pojmenovanou bar(), která metodu vazby vrátí. Kód externí ke třídě vytvoří instanci třídy ThisTest, vyvolá metodu bar() a uchová vrácenou hodnotu v proměnné pojmenované myFunc. class ThisTest { private var num:Number = 3; function foo():void // bound method defined { trace("foo's this: " + this); trace("num: " + num); } function bar():Function { return foo; // bound method returned } } var myTest:ThisTest = new ThisTest(); var myFunc:Function = myTest.bar(); trace(this); // output: [object global] myFunc(); /* output: foo's this: [object ThisTest] output: num: 3 */
Poslední aktualizace 12.5.2011
96
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Objektově orientované programování v jazyce ActionScript
Poslední dva řádky kódu ukazují, že reference this v metodě vazby foo() stále ukazuje na instanci třídy ThisTest, ačkoliv reference this v předcházejícím řádku ukazuje na globální objekt. Navíc metoda vazby uchovaná v proměnné myFunc má stále přístup k proměnným, které jsou členy třídy ThisTest. Jestliže je stejný kód spuštěn v jazyce ActionScript 2.0, reference this bude odpovídat a proměnná num bude undefined. Jedna oblast, kde je přidání metody vazby nejvíce zřejmé, je zpracovávání událostí, protože metoda addEventListener() vyžaduje, abyste funkci nebo metodu odeslali jako argument.
Výčet s třídami Výčty jsou vlastní typy dat, které vytváříte za účelem zapouzdření malé množiny hodnot. Jazyk ActionScript 3.0 nepodporuje na rozdíl od jazyka C++ s klíčovým slovem enum nebo jazyka Java s rozhraním výčtu specifické možnosti výčtu. Výčty můžete nicméně vytvořit pomocí tříd a statických konstant. Například třída PrintJob v jazyce ActionScript 3.0 používá výčet s názvem PrintJobOrientation k uchovávání hodnot „landscape" a „portrait", jak je znázorněno v následujícím kódu: public final class PrintJobOrientation { public static const LANDSCAPE:String = "landscape"; public static const PORTRAIT:String = "portrait"; }
Dle úmluvy je třída výčtu deklarována s atributem final, protože není třeba danou třídu rozšířit. Třída obsahuje pouze statické členy, což znamená, že nevytváříte instance dané třídy. Namísto toho přistupujete k hodnotám výčtu přímo prostřednictvím objektu třídy, jak je ukázáno v následujícím výpise kódu. var pj:PrintJob = new PrintJob(); if(pj.start()) { if (pj.orientation == PrintJobOrientation.PORTRAIT) { ... } ... }
Všechny třídy výčtu v jazyce ActionScript 3.0 obsahují pouze proměnné typu Řetězec, int nebo uint. Výhodou použití výčtu namísto řetězce literálu nebo číselných hodnot je to, že pomocí výčtu naleznete snadněji typografické chyby. Jestliže špatně zadáte název výčtu, kompilátor jazyka ActionScript vygeneruje chybu. Jestliže používáte hodnoty literálu, kompilátor nezjistí chybu, jestliže slovo špatně napíšete nebo použijete špatné číslo. V předchozím příkladu kompilátor vygeneruje chybu, jestliže je název konstanty výčtu nesprávný: if (pj.orientation == PrintJobOrientation.PORTRAI) // compiler error
Nicméně kompilátor nevygeneruje chybu, jestliže špatně napíšete hodnotu řetězce literálu: if (pj.orientation == "portrai") // no compiler error
Druhá technika pro vytvoření výčtů také zahrnuje vytvoření samostatné třídy se statickými vlastnostmi pro výčet. Tato technika se nicméně liší v tom, že každá ze statických vlastností obsahuje instanci dané třídy, namísto řetězce nebo celočíselné hodnoty. Například následující kód vytvoří třídu výčtu pro dny v týdnu:
Poslední aktualizace 12.5.2011
97
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Objektově orientované programování v jazyce ActionScript
public final class Day { public static const public static const public static const public static const public static const public static const public static const }
MONDAY:Day = new Day(); TUESDAY:Day = new Day(); WEDNESDAY:Day = new Day(); THURSDAY:Day = new Day(); FRIDAY:Day = new Day(); SATURDAY:Day = new Day(); SUNDAY:Day = new Day();
Tato technika není používána jazykem ActionScript 3.0, ale je používána mnoha vývojáři, kteří upřednostňují vylepšený typ kontroly, který tato technika nabízí. Například metoda, která vrátí hodnotu výčtu, může omezit vrácenou hodnotu na datový typ výčtu. Následující kód ukazuje nejen funkci, která vrátí den v týdnu, ale také volání funkce, které používá typ výčtu jako typ anotace: function getDay():Day { var date:Date = new Date(); var retDay:Day; switch (date.day) { case 0: retDay = Day.MONDAY; break; case 1: retDay = Day.TUESDAY; break; case 2: retDay = Day.WEDNESDAY; break; case 3: retDay = Day.THURSDAY; break; case 4: retDay = Day.FRIDAY; break; case 5: retDay = Day.SATURDAY; break; case 6: retDay = Day.SUNDAY; break; } return retDay; } var dayOfWeek:Day = getDay();
Třídu Day můžete také vylepšit tak, aby propojila celé číslo s každým dnem v týdnu a poskytla metodu toString(), která vrátí reprezentaci řetězce daného dne.
Poslední aktualizace 12.5.2011
98
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Objektově orientované programování v jazyce ActionScript
Třídy vloženého datového zdroje Jazyk ActionScript 3.0 používá speciální třídy, nazvané třídy vloženého datového zdroje, pro reprezentaci vložených datových zdrojů. vložený datový zdroj je zdroj, jako například zvuk, obraz, nebo typ písma, který je zahrnut do souboru SWF v čase kompilace. Vložení datového zdroje místo jeho dynamického načtení zajistí jeho dostupnost za běhu, ale na druhou stranu také zvýší velikost souboru SWF.
Použití tříd vloženého datového zdroje v aplikaci Flash Professional Pro vložení datového zdroje nejprve umístěte zdroj do knihovny souboru FLA. Poté pomocí vlastnosti propojení datového zdroje poskytněte název pro třídu vloženého datového zdroje. Jestliže nemůže být třída dle daného názvu nalezena v cestě třídy, je pro vás automaticky vygenerována. Poté můžete vytvořit instanci třídy vloženého datového zdroje a použít jakékoliv vlastnosti a metody definované nebo zděděné danou třídou. Například následující kód lze použít pro přehrání vloženého zvuku, který je propojen s třídou vloženého datového zdroje s názvem PianoMusic: var piano:PianoMusic = new PianoMusic(); var sndChannel:SoundChannel = piano.play();
K vložení datových zdrojů do projektu aplikace Flash Professional lze rovněž použít tag metadat [Embed] (popsáno v následující části). Při použití tagu metadat [Embed] ve vytvořeném kódu provede aplikace Flash Professional kompilaci projektu pomocí kompilátoru Flex místo kompilátoru Flash Professional.
Použití tříd vloženého datového zdroje pomocí kompilátoru Flex Jestliže kompilujete kód pomocí kompilátoru Flex, vložte datový zdroj do kódu jazyka ActionScript pomocí tagu metadat [Embed]. Umístěte datový zdroj do hlavní složky zdroje nebo do jiné složky, která je v cestě k sestavení vašeho projektu. Když se kompilátor Flex setká se značkou metadat Embed, vytvoří třídu vloženého datového zdroje. Třída je přístupná pomocí proměnné s datovým typem Class, kterou deklarujete ihned po příznaku metadat [Embed]. Například následující kód vloží zvuk pojmenovaný sound1.mp3 a použije proměnnou nazvanou soundCls pro uchování odkazu na třídu vloženého datového zdroje propojenou s daným zvukem. Příklad poté vytvoří instanci třídy vloženého datového zdroje a na dané instanci vyvolá metodu play(): package { import flash.display.Sprite; import flash.media.SoundChannel; import mx.core.SoundAsset; public class SoundAssetExample extends Sprite { [Embed(source="sound1.mp3")] public var soundCls:Class; public function SoundAssetExample() { var mySound:SoundAsset = new soundCls() as SoundAsset; var sndChannel:SoundChannel = mySound.play(); } } }
Poslední aktualizace 12.5.2011
99
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Objektově orientované programování v jazyce ActionScript
Adobe Flash Builder Aby bylo možné použít v projektu Flex Builder jazyka ActionScript tag metadat [Embed], je třeba importovat všechny nezbytné třídy z rámce Flex. Pro vkládání zvuků je například nutné importovat třídu mx.core.SoundAsset. Pro použití rámce Flex začleňte soubor framework.swc do cesty k sestavení jazyka ActionScript. Tím se zvětší velikost souboru SWF.
Adobe Flex V rozhraní Flex lze vložit datový zdroj také pomocí příkazu @Embed() v definici tagu MXML.
Rozhraní Rozhraní je skupinou deklarací metody, které umožňují nesouvisejícím objektům navzájem komunikovat. Například jazyk ActionScript 3.0 definuje rozhraní IEventDispatcher, které obsahuje deklarace metody, kterou třída používá pro zpracování objektů události. Rozhraní IEventDispatcher zavádí standardní způsob pro vzájemné předání objektů událostí. Následující kód ukazuje definici rozhraní IEventDispatcher interface: public interface IEventDispatcher { function addEventListener(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean = false):void; function removeEventListener(type:String, listener:Function, useCapture:Boolean=false):void; function dispatchEvent(event:Event):Boolean; function hasEventListener(type:String):Boolean; function willTrigger(type:String):Boolean; }
Rozhraní jsou založena na rozdílu mezi rozhraním metody a její implementací. Rozhraní metody obsahuje všechny potřebné informace pro volání dané metody, včetně názvu metody, všech její parametrů a jejího typu návratu. Implementace metody nezahrnuje pouze informace o rozhraní, ale také proveditelné příkazy, které provedou chování metody. Definice rozhraní obsahuje pouze rozhraní metody a jakákoliv třída, která implementuje dané rozhraní, je odpovědná za definici implementací metody. V jazyce ActionScript 3.0 implementuje třída EventDispatcher rozhraní IEventDispatcher definováním všech metod rozhraní IEventDispatcher a přidáním těl metod ke každé z těchto metod. Následující kód je výpisem z definice třídy EventDispatcher: public class EventDispatcher implements IEventDispatcher { function dispatchEvent(event:Event):Boolean { /* implementation statements */ } ... }
Rozhraní IEventDispatcher slouží jako protokol, který instance EventDispatcher používají pro zpracování objektů události a jejich předání k jiným objektům, které také mají implementováno rozhraní IEventDispatcher.
Poslední aktualizace 12.5.2011
100
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Objektově orientované programování v jazyce ActionScript
Dalším způsobem popsání rozhraní je to, že stejně jako třída definuje datový typ. Podle toho může být rozhraní použito jako typ anotace i jako třída. Jako datový typ lze rozhraní použít s operátory, jako například is a as, které vyžadují datový typ. Narozdíl od třídy nemůže být rozhraní konkretizováno. Tento rozdíl donutil mnoho programátorů přemýšlet o rozhraních jako o abstraktních datových typech a třídách jako o konkrétních datových typech.
Definice rozhraní Struktura definice rozhraní je podobná struktuře definice třídy s výjimkou, že rozhraní může obsahovat pouze metody bez těl. Rozhraní nemůže zahrnovat proměnné nebo konstanty, ale může obsahovat mechanismy získání a nastavení. Pro definování rozhraní použijte klíčové slovo interface. Například následující rozhraní, IExternalizable, je součástí balíku ActionScript 3.0. Rozhraní IExternalizable definuje protokol pro serializaci objektu, což znamená jeho převedení do formátu vhodného k uložení na zařízení nebo pro přesun po síti. public interface IExternalizable { function writeExternal(output:IDataOutput):void; function readExternal(input:IDataInput):void; }
Dané rozhraní IExternalizable je deklarováno pomocí modifikátoru řízení přístupu public. Definice rozhraní lze upravit pouze pomocí specifikátorů řízení přístupu public a internal. Deklarace metody uvnitř definice rozhraní nemohou mít žádné specifikátory ovládání přístupu. Jazyk ActionScript 3.0 se řídí ustanovením, kde názvy rozhraní začínají velkým I, ale jako název rozhraní můžete použít jakýkoliv povolený identifikátor. Definice rozhraní jsou často umístěny na nevyšší úrovni balíku. Definice rozhraní nelze umístit dovnitř definice třídy nebo dovnitř jiné definice rozhraní. Rozhraní mohou rozšířit jedno nebo více jiných rozhraní. Například následující rozhraní IExample rozšiřuje rozhraní IExternalizable: public interface IExample extends IExternalizable { function extra():void; }
Jakákoliv třída, která implementuje rozhraní, musí zahrnovat implementace nejen pro metodu extra(), ale také pro metodywriteExternal() a readExternal() zděděné z rozhraní IExternalizable.
Implementace rozhraní ve třídě Třída je jediným prvkem jazyka ActionScript 3.0, který může implementovat rozhraní. Pomocí klíčového slova implements v deklaraci třídy implementujete jedno nebo více rozhraní. Následující příklad definuje dvě rozhraní IAlpha a IBeta a třídu Alfa, která je obě implementuje.
Poslední aktualizace 12.5.2011
101
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Objektově orientované programování v jazyce ActionScript
interface IAlpha { function foo(str:String):String; } interface IBeta { function bar():void; } class Alpha implements IAlpha, IBeta { public function foo(param:String):String {} public function bar():void {} }
Ve třídě, která implementuje rozhraní, musí implementovaná metoda provést následující:
• Použijte identifikátor ovládání přístupu public. • Použijte stejný název jako má metoda rozhraní. • Mají stejný počet parametrů s typy dat, které odpovídají datovým typům parametrů metody rozhraní. • Použijte stejný typ návratu. public function foo(param:String):String {}
Jistou flexibilitu máte nicméně v tom, jak pojmenujete parametry metody, kterou implementujete. Ačkoliv počet parametrů a datový typ každého parametru v dané implementované metodě musí odpovídat parametru metody rozhraní, názvy parametrů odpovídat nemusí. Například v předchozím příkladě je parametr metody Alpha.foo() pojmenovaný param: Nicméně parametr je pojmenovaný str v metodě rozhraní IAlpha.foo(): function foo(str:String):String;
Určitou flexibilitu máte také s výchozími hodnotami parametru. Definice rozhraní může zahrnovat deklarace funkce s výchozími hodnotami parametrů. Metoda, která implementuje takovou deklaraci funkce, musí mít výchozí hodnotu parametru, který je členem stejného datového typu, shodnou s hodnotou určenou v definici rozhraní, ale skutečná hodnota nemusí odpovídat. Například následující kód definuje rozhraní, které obsahuje metodu s výchozí hodnotou parametru 3: interface IGamma { function doSomething(param:int = 3):void; }
Následující definice třídy implementuje rozhraní IGamma, ale používá odlišnou výchozí hodnotu parametru: class Gamma implements IGamma { public function doSomething(param:int = 4):void {} }
Důvodem pro tuto flexibilitu je to, že pravidla pro implementování rozhraní jsou navržena specificky pro zajištění kompatibility typu dat a vyžadování identických názvů parametrů a výchozích hodnot parametrů není pro dosažení daného cíle nezbytné.
Poslední aktualizace 12.5.2011
102
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Objektově orientované programování v jazyce ActionScript
Zdědění Dědičnost je formou opětovného použití kódu, které programátorům umožňuje vyvinout nové třídy, které jsou založeny na stávajících třídách. Stávající třídy jsou často označovány jako základní třídy nebo nadřazené třídy, zatímco nové třídy se obvykle nazývají podtřídy. Klíčovou výhodou dědičnosti je to, že vám umožňuje znovu použít kód ze základní třídy a přesto ponechat stávající kód bez změn. A navíc, dědičnost nevyžaduje žádné změny způsobu, kterým jiné třídy reagují se základní třídou. Spíše než úpravou stávající třídy, která mohla být řádně testována nebo může již být používána, můžete pomocí dědičnosti manipulovat s danými třídami jako s integrovaným modulem, který můžete rozšířit o dodatečné vlastnosti nebo metody. Stejně tak pomocí klíčového slova extends určíte, že třída dědí z jiné třídy. Dědičnost vám také umožňuje využít ve svém kódu polymorfismus. Polymorfismus je schopnost použít jediný název metody pro metodu, která se chová jinak při použití jiných typů dat. Jednoduchým příkladem je základní třída pojmenovaná Shape s dvěma podtřídami pojmenovanými Circle a Square. Třída Shape definuje metodu pojmenovanou area(), která vrací prostor tvaru. Jestliže je implementován polymorfismus, můžete metodu area() vyvolat na objekty typu Circle a Square a provést správné výpočty. Dědičnost aktivuje polymorfismus umožněním podtřídám zdědit, předefinovat nebo potlačit metody ze základní třídy. V následujícím příkladě je metoda area() předefinována třídami Circle a Square: class Shape { public function area():Number { return NaN; } } class Circle extends Shape { private var radius:Number = 1; override public function area():Number { return (Math.PI * (radius * radius)); } } class Square extends Shape { private var side:Number = 1; override public function area():Number { return (side * side); } } var cir:Circle = new Circle(); trace(cir.area()); // output: 3.141592653589793 var sq:Square = new Square(); trace(sq.area()); // output: 1
Protože každá třída definuje typ dat, vytvoří použití dědičnosti zvláštní vztah mezi základní třídou a třídou, která jí prodlužuje. Podtřída vlastní všechny vlastnosti své základní třídy, což znamená, že instance podtřídy může být vždy nahrazena za instanci základní třídy. Například jestliže metoda definuje parametr typu Shape, je možné předat argument typu Circle, protože Circle rozšiřuje Shape, a to následovně:
Poslední aktualizace 12.5.2011
103
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Objektově orientované programování v jazyce ActionScript
function draw(shapeToDraw:Shape) {} var myCircle:Circle = new Circle(); draw(myCircle);
Vlastnosti a dědičnost instancí Vlastnost instance, ať už definovaná pomocí klíčových slov function, var nebo const, je děděna všemi podtřídami, pokud daná vlastnost není v základní třídě deklarována s atributem private. Například třída Event v jazyce ActionScript 3.0 má několik podtříd, které dědí vlastnosti společné pro všechny objekty události. Pro některé typy událostí třída Event obsahuje všechny vlastnosti nezbytné pro definici události. Tyto typy událostí nevyžadují vlastnosti instancí mimo těch definovaných ve třídě Event. Příklady takových událostí jsou událost complete, ke které doje při úspěšném načtení dat a událost connect, ke které dojde při navázání síťového spojení. Následující příklad je výpisem ze třídy Event, která vykazuje některé z vlastností a metod, které jsou zděděny podtřídou. Protože jsou vlastnosti zděděné, má k těmto vlastnostem přístup instance jakékoliv podtřídy. public class Event { public function get type():String; public function get bubbles():Boolean; ... public public public public ...
function function function function
stopPropagation():void {} stopImmediatePropagation():void {} preventDefault():void {} isDefaultPrevented():Boolean {}
}
Jiné typy události vyžadují jedinečné vlastnosti, které nejsou dostupné ve třídě Event. Tyto události jsou definovány pomocí podtříd třídy Event, takže nové vlastnosti lze přidat k vlastnostem definovaným ve třídě Event. Příkladem takové podtřídy je třída MouseEvent, která přidává vlastnosti jedinečné k události spojené s pohybem nebo klepnutím myši, například k události mouseMove a click. Následující příklad je výpisem z třídy MouseEvent, která ukazuje definici vlastností, které existují na dané podtřídě, ale nikoliv na základní třídě: public class MouseEvent extends Event { public static const CLICK:String= "click"; public static const MOUSE_MOVE:String = "mouseMove"; ... public function get stageX():Number {} public function get stageY():Number {} ... }
Specifikátory ovládání přístupu a dědičnost Jestliže je vlastnost deklarována pomocí klíčového slova public, je vlastnost pro kód viditelná kdekoliv. To znamená, že klíčové slovo public, narozdíl od klíčových slov private, protected a internalneuplatňuje na dědičnost vlastnosti žádná omezení. Jestliže je vlastnost deklarována pomocí klíčového slova private, je viditelná pouze ve třídě, která je definuje, což znamená, že není děděná žádnou podtřídou. Toto chování je odlišné od předchozích verzí jazyka ActionScript, kde se klíčové slovo private chovalo více jako klíčové slovo jazyka ActionScript protected.
Poslední aktualizace 12.5.2011
104
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Objektově orientované programování v jazyce ActionScript
Klíčové slovo protected udává, že je vlastnost viditelná nejen v rámci třídy, která ji definuje, ale také pro všechny podtřídy. Narozdíl od klíčového slova protected v programovacím jazyce Java, klíčové slovo protected v jazyce ActionScript 3.0 nezviditelňuje vlastnost pro všechny jiné třídy ve stejném balíku. V jazyce ActionScript 3.0 mají k vlastnosti s klíčovým slovem protected přístup pouze podtřídy. Chráněná vlastnost je navíc viditelná pro podtřídy, ať je podtřída ve stejném balíku jako daná třída, nebo v balíku odlišném. Chcete-li omezit viditelnost vlastnosti na balík, ve kterém je definovaná, použijte klíčové slovo internal, nebo nepoužijte žádný specifikátor ovládání přístupu. Specifikátor ovládání přístupu internal je výchozím specifikátorem ovládání přístupu, který bude použit v případě, že jiný specifikátor určen není. Vlastnost označenou jako internal zdědí pouze podtřída, která se nachází ve stejném balíku. Pomocí následujícího příkladu zjistíte, jak každý ze specifikátorů ovládání přístupu ovlivní dědičnost napříč hranicemi balíku. Následující kód definuje hlavní třídu aplikace nazvanou AccessControl a dvě další třídy pojmenované Base a Extender. Třída Base se nachází v balíku pojmenovaném foo a třída Extender, která je podtřídou třídy Base, je umístěna v balíku pojmenovaném bar. Třída AccessControl importuje pouze třídu Extender a vytvoří instanci Extender, která se pokusí o přístup k proměnné pojmenované str definované ve třídě Base. Proměnná str je deklarovaná jako public, takže kód je sestaven a běží tak, jak je ukázáno v následujícím výpise: // Base.as in a folder named foo package foo { public class Base { public var str:String = "hello"; // change public on this line } } // Extender.as in a folder named bar package bar { import foo.Base; public class Extender extends Base { public function getString():String { return str; } } } // main application class in file named AccessControl.as package { import flash.display.MovieClip; import bar.Extender; public class AccessControl extends MovieClip { public function AccessControl() { var myExt:Extender = new Extender(); trace(myExt.str);// error if str is not public trace(myExt.getString()); // error if str is private or internal } } }
Poslední aktualizace 12.5.2011
105
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Objektově orientované programování v jazyce ActionScript
Chcete-li vědět, jak jiné specifikátory ovládání přístupu ovlivňují kompilaci a provedení předchozího příkladu, změňte specifikátor ovládání přístupu proměnné str na private, protected nebo internal, a to po odstranění nebo okomentování následujícího řádku ze třídy AccessControl: trace(myExt.str);// error if str is not public
Potlačení proměnných není povoleno Vlastnosti deklarované s klíčovými slovy var nebo const jsou zděděny, ale nemohou být potlačeny. Potlačit vlastnost znamená předefinovat danou vlastnost v podtřídě. Jediným typem vlastnosti, který může být potlačen, jsou přístupové mechanismy získání a nastavení (vlastnosti deklarované pomocí klíčového slova function). Ačkoliv nelze potlačit proměnnou instance, podobné funkce můžete dosáhnout vytvořením metod získání a nastavení pro proměnou instance a potlačením metod.
Potlačování metod Potlačení metody znamená nové definování chování zděděné metody. Statické metody nejsou zděděné a nelze je potlačit. Metody instance jsou nicméně zděděny podtřídami a lze je potlačit pokud jsou splněna dvě kritéria:
• Metoda instance není deklarována pomocí klíčového slova final v základní třídě. Je-li používáno s metodou instance, určuje klíčové slovo final záměr programátora zabránit podtřídám potlačit danou metodu.
• Metoda instance není deklarována pomocí specifikátoru ovládání private v základní třídě. Jestliže je metoda v základní třídě označena jako private, potom při definování metody se stejným názvem v podtřídě není nutné použít klíčové slovo override, protože metoda základní třídy nebude pro podtřídu viditelná. Chcete-li potlačit metodu instance, která splňuje tato kritéria, definice metody v podtřídě musí použít klíčové slovo override a musí odpovídat verzi metody nadřazené třídy, a to následovně:
• Metoda potlačení musí mít stejnou úroveň ovládání přístupu, jako metoda základní třídy. Metoda označená jako interní má stejnou úroveň ovládání přístupu jako metody, které nemají žádný specifikátor ovládání přístupu.
• Metoda potlačení musí mít stejný počet parametrů jako metoda základní třídy. • Parametry metody potlačení musí mít stejné anotace typu dat, jako mají parametry v metodě základní třídy. • Metoda potlačení musí mít stejný typ vrácení jako metoda základní třídy. Názvy parametrů v dané metodě potlačení nicméně nemusí odpovídat názvům parametrů v základní třídě, jestliže počet parametrů a typ dat každého parametru souhlasí. Příkaz super Při potlačování metody si programátoři často přejí přidat k chování metody nadřazené třídy, kterou potlačují, namísto úplného nahrazení chování. To vyžaduje mechanismus, který umožňuje metodě podtřídy vyvolat vlastní verzi nadřazené třídy. Příkaz super takový mechanismus poskytuje, protože obsahuje odkaz na další nadřazenou třídu. Následující příklad definuje třídu pojmenovanou Base, která obsahuje metodu pojmenovanou thanks() a podtřídu třídy Base pojmenovanou Extender, která potlačí metodu thanks(). Metoda Extender.thanks() používá příkaz super pro vyvolání Base.thanks().
Poslední aktualizace 12.5.2011
106
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Objektově orientované programování v jazyce ActionScript
package { import flash.display.MovieClip; public class SuperExample extends MovieClip { public function SuperExample() { var myExt:Extender = new Extender() trace(myExt.thanks()); // output: Mahalo nui loa } } } class Base { public function thanks():String { return "Mahalo"; } } class Extender extends Base { override public function thanks():String { return super.thanks() + " nui loa"; } }
Potlačení mechanismů získání nebo nastavení Ačkoliv nemůžete potlačit proměnné definované v nadřazené třídě, můžete potlačit mechanismy získání a nastavení. Například následující kód potlačí mechanismus získání currentLabel, který je definován ve třídě MovieClip v jazyce ActionScript 3.0: package { import flash.display.MovieClip; public class OverrideExample extends MovieClip { public function OverrideExample() { trace(currentLabel) } override public function get currentLabel():String { var str:String = "Override: "; str += super.currentLabel; return str; } } }
Výstup příkazu trace() v konstruktoru třídy OverrideExample je Override: null, který ukazuje, že daný příklad byl schopen potlačit zděděnou vlastnost currentLabel.
Poslední aktualizace 12.5.2011
107
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Objektově orientované programování v jazyce ActionScript
Statické vlastnosti nezděděné Statické vlastnosti nejsou zděděny podtřídami. To znamená, že statistické vlastnosti nejsou přístupné prostřednictvím instance nadřazené třídy. Statická vlastnost je přístupná pouze prostřednictvím objektu třídy, na které je definovaná. Například následující kód definuje základní třídu pojmenovanou Base a podtřídu, která rozšiřuje základní třídu, pojmenovanou Extender. Statická proměnná pojmenovaná test je definována ve třídě Base. Kód, jak je zapsán v následujícím výpise, není slučitelný s přísným režimem a ve standardním režimu vytvoří chybu za běhu programu. package { import flash.display.MovieClip; public class StaticExample extends MovieClip { public function StaticExample() { var myExt:Extender = new Extender(); trace(myExt.test);// error } } } class Base { public static var test:String = "static"; } class Extender extends Base { }
Jediný způsob přístupu ke statické proměnné test je prostřednictvím objektu třídy, jak je ukázáno v následujícím kódu: Base.test;
Nicméně je povolené definovat vlastnost instance použitím stejného názvu jako statické vlastnosti. Taková vlastnost instance může být definována ve stejné třídě jako statická vlastnost nebo v podtřídě. Například základní třída v předcházejícím příkladě by mohla mít vlastnost instance pojmenovanou test. Následující kód je sestaven a proveden, protože vlastnost instance je zděděna třídou Extender. Kód by byl také sestaven a proveden, pokud by byla definice testové proměnné instance přesunuta, ale nikoliv zkopírována, do třídy Extender. package { import flash.display.MovieClip; public class StaticExample extends MovieClip { public function StaticExample() { var myExt:Extender = new Extender(); trace(myExt.test);// output: instance } } } class Base { public static var test:String = "static"; public var test:String = "instance"; } class Extender extends Base {}
Poslední aktualizace 12.5.2011
108
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Objektově orientované programování v jazyce ActionScript
Statistické vlastnosti a řetězec rozsahu Ačkoliv statické vlastnosti nejsou zděděny, existují v rámci řetězce rozsahu třídy, která definuje tyto vlastnosti a jakékoliv podtřídy dané třídy. Jako takové jsou statické vlastnosti v rozsahu třídy, ve které jsou definovány, i jakékoliv podtřídy. To znamená, že statická vlastnost je přímo přístupná v rámci těla třídy, která definuje statickou vlastnost a v jakékoliv podtřídě dané třídy. Následující příklad upravuje třídy definované v předchozím příkladě a ukazuje, že statická proměnná test definovaná v základní třídě je v rozsahu třídy Extender. Jinými slovy třída Extender má přístup k statické proměnné test bez toho, aby byla proměnná opatřena předponou s názvem třídy, která definuje test. package { import flash.display.MovieClip; public class StaticExample extends MovieClip { public function StaticExample() { var myExt:Extender = new Extender(); } } } class Base { public static var test:String = "static"; } class Extender extends Base { public function Extender() { trace(test); // output: static } }
Jestliže je definovaná vlastnost instance, která používá stejný název jako statická vlastnost ve stejné třídě nebo nadřazené třídě, vlastnost instance má v řetězci rozsahu vyšší prioritu. Vlastnost instance stíní statickou vlastnost, což znamená, že hodnota vlastnosti instance je použita namísto hodnoty statické vlastnosti. Například následující kód ukazuje, že jestliže třída Extender definuje proměnnou instance pojmenovanou test, příkaz trace() používá hodnotu proměnné instance namísto hodnoty statické proměnné:
Poslední aktualizace 12.5.2011
109
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Objektově orientované programování v jazyce ActionScript
package { import flash.display.MovieClip; public class StaticExample extends MovieClip { public function StaticExample() { var myExt:Extender = new Extender(); } } } class Base { public static var test:String = "static"; } class Extender extends Base { public var test:String = "instance"; public function Extender() { trace(test); // output: instance } }
Pokročilá témata Historie podpory OOP jazyka ActionScript Protože jazyk ActionScript 3.0 navazuje na předchozí verze jazyka ActionScript, může být užitečné pochopit, jak se model objektu jazyka ActionScript vyvinul. Jazyk ActionScript začal jako jednoduchý skriptovací mechanismus pro dřívější verze aplikace Flash Professional. Později začali programátoři pomocí jazyka ActionScript vytvářet komplexnější aplikace. V reakci na potřeby těchto programátorů má každá následující verze nové funkce jazyka, které umožňují vytváření složitých aplikací. Jazyk ActionScript 1.0 Jazyk ActionScript 1.0 je verze jazyka použitá v přehrávači Flash Player 6 a v dřívějších verzích. I v této ranné fázi vývoje byl model objektu jazyka ActionScript založen na konceptu objektu jako základního typu dat. Objekt jazyka ActionScript je složený typ dat se skupinou vlastností. Hovoříme-li o modelu objektu, pojem vlastnosti zahrnuje vše, co je připojeno k objektu. Jedná se například o proměnné, funkce nebo metody. Ačkoliv první generace jazyka ActionScript nepodporuje definici tříd pomocí klíčového slova class, můžete definovat třídu pomocí speciálního druhu objektu nazvaného objekt prototypu. Namísto použití klíčového slova class pro vytvoření definice třídy, kterou zkonkretizujete do určitých objektů, jak to děláte v jazycích založených na třídě (Java a C++), jazyky založené na prototypu (ActionScript 1.0) používají stávající objekt jako model (nebo prototyp) pro jiné objekty. Zatímco objekty v jazyce založeném na třídě mohou indikovat třídu, která slouží jako její šablona, objekty v jazyce založeném na prototypu namísto toho ukazují na jiný objekt, svůj prototyp, který slouží jako šablona.
Poslední aktualizace 12.5.2011
110
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Objektově orientované programování v jazyce ActionScript
Pro vytvoření třídy v jazyce ActionScript 1.0 vytvoříte pro danou třídu funkci konstruktoru. V jazyce ActionScript jsou funkce skutečné objekty, nikoliv pouze abstraktní definice. Funkce konstruktoru, kterou vytváříte, slouží jako prototypický objekt pro instance dané třídy. Následující kód vytvoří třídu pojmenovanou Shape a definuje jednu vlastnost pojmenovanou visible, která je implicitně nastavena na hodnotu true (pravda): // base class function Shape() {} // Create a property named visible. Shape.prototype.visible = true;
Tato funkce konstruktoru definuje třídu Shape, kterou můžete konkretizovat pomocí operátoru new, a to následovně: myShape = new Shape();
Stejně jako slouží objekt funkce konstruktoru Shape() jako prototyp pro instance třídy tvaru, může také sloužit jako prototyp pro podtřídy tvaru - tj. pro další třídy, které rozšiřují třídu Shape. Vytvoření třídy, která je podtřídou třídy Shape, je proces zahrnující dva kroky. Nejprve vytvořte třídu tím, že pro danou třídu definujete funkci konstruktoru: // child class function Circle(id, radius) { this.id = id; this.radius = radius; }
Poté použijte operátor new za účelem deklarování, která třída Shape je prototypem třídy Circle. Každá třída, kterou vytvoříte, implicitně používá třídu Object jako prototyp, což znamená, že Circle.prototype aktuálně obsahuje generický objekt (instance třídy Object). Pro určení, že prototyp kruhu je tvar a nikoliv objekt, použijte následující kód pro změnu hodnoty Circle.prototype tak, aby obsahovala objekt tvaru namísto generického objektu: // Make Circle a subclass of Shape. Circle.prototype = new Shape();
Třídy Shape a Circle jsou nyní navzájem propojeny ve vztahu dědičnosti, který je běžně znám jako řetězec prototypu. Tento diagram ilustruje vztah v řetězci prototypu: Object.prototype
Shape.prototype
Circle.prototype
Základní třída na konci každého řetězce prototypu je třída Object. Třída Object obsahuje statickou vlastnost s názvem Object.prototype, která ukazuje na základní objekt prototypu pro všechny objekty vytvořené v jazyce ActionScript 1.0. Další objekt v řetězci prototypu našeho příkladu je objekt Shape. Důvod je ten, že vlastnost Shape.prototype nebyla nikdy explicitně nastavena, takže stále obsahuje generický objekt (instanci třídy Object). Závěrečný odkaz v tomto řetězci je třída Circle, které je propojena se svým prototypem, tedy třídou Shape (vlastnost Circle.prototype obsahuje objekt Shape). Jestliže vytvoříte instanci třídy Circle jako v následujícím příkladu, zdědí daná instance řetězec prototypu třídy Circle: // Create an instance of the Circle class. myCircle = new Circle();
Poslední aktualizace 12.5.2011
111
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Objektově orientované programování v jazyce ActionScript
Vzpomeňte si, že příklad zahrnoval vlastnost s názvem visible jako člena třídy Shape. V tomto příkladu vlastnost visible neexistuje jako součást objektu myCircle, ale pouze jako člen objektu Shape. Přesto má ale následující řádek kódu výsledek true (pravda): trace(myCircle.visible); // output: true
Běhový modul může zjistit, že objekt myCircle zdědí vlastnost visible, a to procházením řetězce prototypu směrem vzhůru. Při provádění tohoto kódu se běhový modul nejprve pokusí vyhledat ve vlastnostech objektu myCircle vlastnost s názvem visible, ale nenalezne ji. Následně se podívá do objektu Circle.prototype, ale ani pak vlastnost pojmenovanou visible nenalezne. Bude řetězcem procházet dále a nakonec nalezne vlastnost visible definovanou na objektu Shape.prototype a vyprodukuje hodnotu dané vlastnosti. V zájmu zachování jednoduchosti je vynechána řada detailů a spletitostí řetězce prototypu. Místo toho je cílem poskytnout dostatek informací, díky nimž snáze pochopíte objektový model jazyka ActionScript 3.0. ActionScript 2.0 Jazyk ActionScript 2.0 zavedl nová klíčová slova, například class, extends, public a private, které vám umožnily definovat třídy způsobem známým všem, kteří pracují s jazyky založenými na třídě, jako jsou Java a C++. Je důležité pochopit, že výchozí mechanismus dědičnosti se mezi jazyky ActionScript 1.0 a ActionScript 2.0 nezměnil. Jazyk ActionScript 2.0 pouze přidal novou syntaxi pro definování tříd. Řetězec prototypu funguje v obou verzích jazyka stejně. Nová syntaxe zavedená jazykem ActionScript 2.0, zobrazená v následujícím výpise, vám umožňuje definovat třídy způsobem, který je pro mnoho programátorů intuitivnější. // base class class Shape { var visible:Boolean = true; }
Všimněte si, že jazyk ActionScript 2.0 také zavedl typ anotací, které budou použity pro kontrolu času kompilace. To vám umožní deklarovat, že by vlastnost visible v předchozím příkladě měla obsahovat pouze booleovskou hodnotu. Nové klíčové slovo extends také zjednodušuje proces vytváření podtřídy. V následujícím příkladě je proces se dvěma kroky v jazyce ActionScript 1.0 dokončen jedním krokem, a to pomocí klíčového slova extends: // child class class Circle extends Shape { var id:Number; var radius:Number; function Circle(id, radius) { this.id = id; this.radius = radius; } }
Konstruktor je nyní deklarován jako část definice třídy a vlastnosti třídy id a radius musí být také explicitně deklarovány. Jazyk ActionScript 2.0 také přidal podporu pro definici rozhraní, která vám umožňuje dále předefinovat své programy orientované na objekt s formálně definovanými protokoly pro komunikaci mezi objekty.
Poslední aktualizace 12.5.2011
112
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Objektově orientované programování v jazyce ActionScript
Objekt třídy v jazyce ActionScript 3.0 Běžné paradigma programování orientované na objekt, které je nejčastěji spojené s jazyky Java a C++, používá třídy pro definici tříd objektů. Programovací jazyky, které přijímají toto paradigma, také často používají třídy pro konstrukci instancí typu dat, které třída definuje. Jazyk ActionScript používá třídy pro oba tyto způsoby, ale jeho základ jazyka založeného na prototypu přidává další zajímavé vlastnosti. Jazyk ActionScript vytváří pro každou definici třídy zvláštní objekt třídy, která umožňuje sdílení chování i stavu. Pro mnoho programátorů jazyka ActionScript nicméně tento rozdíl nemusí mít žádné praktické implikace pro kód. Jazyk ActionScript 3.0 je navržen tak, že vytváříte sofistikované aplikace jazyka ActionScript orientované na objekt bez použití, nebo dokonce pochopení, těchto zvláštních objektů tříd. Následující diagram ukazuje strukturu objektu třídy, který představuje jednoduchou třídu pojmenovanou A definovanou pomocí příkazu class A {}: Class.prototype
T
Object.prototype
CA
delegát
typ
C
delegát
prototyp
konstruktor
A
vlastnost
P
A
T
A
Každý obdélník v diagramu představuje objekt. Každý objekt v daném diagramu má charakter dolního indexu A, který představuje to, že náleží do třídy A. Objekt třídy (CA) obsahuje odkazy na několik jiných důležitých objektů. Objekt vlastnosti instance (TA) uchovává vlastnosti instance, které jsou definovány v rámci definice třídy. Objekt vlastnosti třídy (TCA) představuje interní typ třídy a uchovává statické vlastnosti definované danou třídou (znak dolního indexu C znamená „class” - třída). Objekt prototypu (PA) vždy znamená objekt třídy, ke kterému byl původně připojen pomocí vlastnosti constructor.
Objekt vlastnosti Objekt vlastnosti, který je v jazyce ActionScript 3.0 nový, byl implementován s ohledem na výkon. V předcházejících verzích jazyka ActionScript mohlo být vyhledání názvu, kdy přehrávač Flash Player prochází řetězec prototypu, časově náročným procesem. V jazyce ActionScript 3.0 je vyhledání názvu daleko účinnější a méně časově náročné, protože zděděné vlastnosti jsou kopírovány z nadřazených tříd do objektů vlastností podtříd. Objekt vlastnosti není přímo dostupný kódem programátora, ale jeho přítomnost zaznamenáte díky lepšímu výkonu a využití paměti. Objekty vlastností poskytují AVM2 detailní informace o rozvržení a obsahu třídy. Díky této znalosti může AVM2 výrazně zkrátit dobu provedení, protože může často vygenerovat přímé pokyny zařízení pro přístup k vlastnostem nebo může vyvolat metody přímo bez časově náročného vyhledávání názvu. Díky objektu vlastností může být otisk paměti objektu výrazně menší než podobný objekt v předchozích verzích jazyka ActionScript. Jestliže je například třída zapečetěna (tj. třída není deklarovaná jako dynamická), instance třídy nepotřebuje tabulku rušení pro dynamicky přidané vlastnosti a může přestavovat pouze ukazovátko na objekty vlastností a některé bloky pro pevné vlastnosti definované ve třídě. Následkem toho by objekt, který vyžaduje 100 bytů paměti v jazyce ActionScript 2.0, mohl vyžadovat pouze 20 bytů paměti v jazyce ActionScript 3.0.
Poslední aktualizace 12.5.2011
113
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Objektově orientované programování v jazyce ActionScript
Poznámka: Objekt vlastnosti je interním detailem implementace a neexistuje žádná záruka, že se nezmění nebo dokonce v příštích verzích jazyka ActionScript nezmizí.
Objekt prototypu Každý objekt třídy jazyka ActionScript má vlastnost pojmenovanou prototype, která je odkazem na objekt prototypu třídy. Objekt prototypu je odkazem kořenů jazyka ActionScript jako jazyka založeného na prototypu. Pro více informací viz Historie podpory jazyka ActionScript objektově orientovaného programování. Vlastnost prototype je určena pouze ke čtení, což znamená, že nemůže být upravena a odkazovat tak na různé objekty. To se liší od vlastnosti třídy prototype v předchozích verzích jazyka ActionScript, kdy může být prototyp znovu přiřazen tak, aby odkazoval na odlišnou třídu. Ačkoliv je vlastnost prototype určena pouze ke čtení, objekt prototypu, na který odkazuje, není. Jiným slovy, k objektu prototypu lze přidat nové vlastnosti. Vlastnosti přidané k objektu prototypu jsou sdíleny mezi všemi instancemi dané třídy. Řetězec prototypu, který byl jediným mechanismem dědičnosti v předchozích verzích jazyka ActionScript, slouží v jazyce ActionScript 3.0 pouze jako sekundární úloha. Primární mechanismus dědičnosti, dědičnost pevné vlastnosti, je zpracována interně objektem vlastnosti. Pevná vlastnost je proměnná nebo metoda definovaná jako část definice třídy. Dědičnost pevné vlastnosti se také nazývá dědičnost třídy, protože se jedná o mechanismus dědičnosti, který je spojen s klíčovými slovy jako class, extends a override. Řetězec prototypu poskytuje alternativní mechanismus dědičnosti, který je dynamičtější než dědičnost pevné vlastnosti. Vlastnosti k objektu prototypu třídy můžete přidat nejen jako součást definice třídy, ale také v čase zpracování prostřednictvím třídy vlastnosti prototype objektu. Nicméně si všimněte, že jestliže nastavíte kompilátor na přísný režim, nemusíte mít přístup k vlastnostem přidaným k objektu prototypu, pokud nedeklarujete třídu s klíčovým slovem dynamic. Dobrým příkladem třídy s několika vlastnostmi připojené k objektu prototypu je třída Objekt. Metody třídy objektu toString() a valueOf() jsou vlastně funkce přiřazené k vlastnostem objektu prototypu třídy Object. Následující
příklad ukazuje, jak by mohla deklarace těchto metod teoreticky vypadat (skutečná implementace se mírně liší z důvodů detailů implementace). public dynamic class Object { prototype.toString = function() { // statements }; prototype.valueOf = function() { // statements }; }
Jak již bylo zmíněno dříve, můžete připojit vlastnost k objektu prototypu třídy mimo definici třídy. Například metodu toString() lze také definovat mimo definici třídy Object, a to následovně: Object.prototype.toString = function() { // statements };
Poslední aktualizace 12.5.2011
114
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Objektově orientované programování v jazyce ActionScript
Narozdíl od dědičnosti pevné vlastnosti dědičnost prototypu nevyžaduje klíčové slovo override, jestliže si přejete znovu definovat metodu v podtřídě. Například. Jestliže si přejte znovu definovat metodu valueOf() v podtřídě třídy Object, máte tři možnosti. Zaprvé definujete metodu valueOf() na objektu prototypu dílčí třídy uvnitř definice třídy. Následující kód vytvoří podtřídu objektu pojmenovanou Foo a znovu definuje metodu valueOf() na objektu prototypu Foo jako část definice třídy. Protože každá třída dědí ze třídy Object, není třeba použít klíčové slovo extends. dynamic class Foo { prototype.valueOf = function() { return "Instance of Foo"; }; }
Za druhé můžete definovat metodu valueOf() na objektu prototypu Foo mimo definici třídy, dle příkladu v následujícím kódu: Foo.prototype.valueOf = function() { return "Instance of Foo"; };
Za třetí můžete definovat pevnou vlastnost pojmenovanou valueOf() jako část třídy Foo. Tato technika se liší od jiných tím, že kombinuje dědičnost pevné vlastnosti s dědičností prototypu. Jakákoliv podtřída Foo, která chce znovu definovat valueOf(), musí použít klíčové slovo override. Následující kód ukazuje valueOf() definovanou jako pevnou vlastnost v Foo: class Foo { function valueOf():String { return "Instance of Foo"; } }
Obor názvů AS3 Existence dvou oddělených mechanismů dědičnosti, dědičnosti pevné vlastnosti a dědičnosti prototypu, vytváří zajímavou otázku kompatibility s ohledem na vlastnosti a metody tříd jádra. Slučitelnost se specifikací jazyka výkresů ECMAScript, na kterých je jazyk ActionScript založen vyžaduje použití dědičnosti prototypu, což znamená, že vlastnosti a metody třídy jádra jsou definovány na objektu prototypu dané třídy. Na druhou stranu slučitelnost s jazykem ActionScript 3.0 vyžaduje použití dědičnosti pevné vlastnosti, což znamená, že vlastnosti a metody třídy jádra jsou definovány v definici třídy pomocí klíčových slov const, var a function. Navíc použití pevných vlastností namísto verzí prototypů může vést k významnému nárůstu výkonu během zpracovávání. Jazyk ActionScript 3.0 tento problém řeší použitím jak dědičnosti prototypu, tak dědičnosti pevné vlastnosti pro třídy jádra. Každá třída jádra obsahuje dvě množiny vlastností a metod. Jedna množina je definována na objektu prototypu pro slučitelnost se specifikací ECMAScript a druhá je definována pomocí pevných vlastností a jmenného prostoru AS3,0 pro slučitelnost s jazykem ActionScript 3.0. Jmenný prostor AS3 poskytuje výhodný mechanismus pro volbu mezi těmito dvěma množinami vlastností a metod. Jestliže nepoužíváte jmenný prostor AS3, instance třídy jádra dědí vlastnosti a metody definované na objektu prototypu třídy jádra. Jestliže se rozhodnete použít jmenný prostor AS3, instance třídy jádra dědí verze AS3, protože jsou pevné vlastnosti vždy upřednostněny před vlastnostmi prototypu. Jinými slovy, kdykoliv je dostupná pevná vlastnost, je vždy použita namísto stejně pojmenované vlastnosti prototypu.
Poslední aktualizace 12.5.2011
115
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Objektově orientované programování v jazyce ActionScript
Můžete selektivně použít verzi jmenného prostoru AS3 vlastnosti nebo metody, a to její kvalifikací s jmenným prostorem AS3. Například následující kód používá verzi AS3 metody Array.pop(): var nums:Array = new Array(1, 2, 3); nums.AS3::pop(); trace(nums); // output: 1,2
Můžete také použít příkaz use namespace a otevřít tak jmenný prostor AS3 pro všechny definice v rámci bloku kódu. Například následující kód používá příkaz use namespace pro otevření jmenného prostoru AS3 pro metodu pop() i pro metodu push(): use namespace AS3; var nums:Array = new Array(1, 2, 3); nums.pop(); nums.push(5); trace(nums) // output: 1,2,5
Jazyk ActionScript 3.0 také poskytuje volby kompilátoru pro každou sadu vlastností, takže jmenný prostor AS3 můžete použít na celý váš program. Volba kompilátoru -as3 představuje jmenný prostor AS3 a volba -es představuje volbu dědičnosti prototypu (es znamená ECMAScript). Pro otevření jmenného prostoru AS3 pro celý váš program nastavte volbu kompilátoru -as3 na hodnotu true (pravda) a volbu -es na hodnotu false (nepravda). Pro použití verzí prototypu nastavte volby kompilátoru na opačné hodnoty. Výchozí nastavení kompilátoru pro aplikace Flex Builder a Flash Professional jsou -as3 = true (pravda) a -es = false (nepravda). Jestliže si přejete rozšířit jakoukoliv z tříd jádra a potlačit nějakou metodu, měli byste chápat, jak může jmenný prostor AS3 ovlivnit způsob deklarace potlačené metody. Jestliže používáte jmenný prostor AS3, jakékoliv metoda potlačení metody třídy jádra musí také používat jmenný prostor AS3, společně s atributem override. Jestliže jmenný prostor AS3 nepoužíváte a přejete si znovu definovat metodu třídy jádra v podtřídě, neměli byste používat jmenný prostor AS3 ani klíčové slovo override.
Příklad: GeometricShapes Vzorová aplikace GeometricShapes ukazuje, jak lze pomocí jazyka ActionScript 3.0 použít několik konceptů a funkcí orientovaných na objekt, a to včetně:
• Definování tříd • Rozšiřování tříd • Polymorfismus a klíčové slovo override • Definování, rozšiřování a implementace rozhraní Zahrnuje také „metodu rodiny”, která vytváří instanci třídy a ukazuje, jak deklarovat hodnotu vrácení jako instanci rozhraní a použít daný vrácený objekt obecným způsobem. Aplikační soubory pro tuto ukázku najdete na adrese www.adobe.com/go/learn_programmingAS3samples_flash_cz. Soubory aplikace GeometricShapes naleznete ve složce Samples/GeometricShapes. Aplikace sestává z následujících souborů:
Poslední aktualizace 12.5.2011
116
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Objektově orientované programování v jazyce ActionScript
Třída File
Popis
GeometricShapes.mxml
Hlavní soubor aplikace v programu Flash (FLA) nebo Flex (MXML).
nebo GeometricShapes.fla com/example/programmingas3/geometricshapes/IGeometricShape.as
Základní metody definující rozhraní budou implementovány všemi třídami aplikace GeometricShapes.
com/example/programmingas3/geometricshapes/IPolygon.as
Metody definující rozhraní budou implementovány třídami aplikace GeometricShapes, které mají více stran.
com/example/programmingas3/geometricshapes/RegularPolygon.as
Typ geometrického tvaru, jehož strany mají stejnou délku a jsou rozloženy symetricky kolem středu tvaru.
com/example/programmingas3/geometricshapes/Circle.as
Typ geometrického tvaru, který definuje kruh.
com/example/programmingas3/geometricshapes/EquilateralTriangle.as
Podtřída RegularPolygon, která definuje trojúhelník, jehož strany mají stejné délky.
com/example/programmingas3/geometricshapes/Square.as
Podtřída RegularPolygon definující obdélník, jehož všechny strany jsou stejně dlouhé.
com/example/programmingas3/geometricshapes/GeometricShapeFactory.as
Třída obsahující metodu rodiny pro vytvoření tvarů s daným typem tvaru a velikostí.
Definice tříd GeometricShapes Aplikace GeometricShapes umožňuje uživateli specifikovat typ geometrického tvaru a jeho velikost. Tvar poté reaguje s popisem tvaru, jeho oblasti a vzdálenosti okolo jeho obvodu. Uživatelské rozhraní aplikace je triviální, včetně několika kontrol pro výběr typu tvaru, nastavení velikosti a zobrazení popisu. Nejzajímavější část této aplikace je pod povrchem, ve struktuře tříd a samotných rozhraní. Tato aplikace se zabývá geometrickými tvary, ale nezobrazuje je graficky. Třídy a rozhraní, které definují geometrické tvary v tomto příkladě, jsou ukázány v následujícím diagramu pomocí poznámky v jednotném modelovacím jazyce (UML):
Poslední aktualizace 12.5.2011
117
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Objektově orientované programování v jazyce ActionScript
<< rozhraní >> IGeometricShape +getArea (): Number +describe (): Strin
Circle +diameter:Number +Circle () : Circle +getArea () : Number +describe () : String +getCircumference () : Number
<< rozhraní >> IPolygon +getPerimeter (): Number +getSumOfAngles (): Number
RegularPolygon +numSides : int +sideLength : Number +RegularPolygon (): RegularPolygon +getSumOfAngles (): Number +getPerimeter (): Number +getArea (): Number +describe (): String
Square
EquilateralTriangle +EquilateralTriangle (): EquilateralTriangle +getArea (): Number +describe (): String
+Square (): Square +getArea (): Number +describe (): String
Třídy příkladu GeometricShapes
Definice běžného chování s rozhraními Tato aplikace GeometricShapes se zabývá třemi typy tvarů: kruhy, čtverci a rovnostrannými trojúhelníky. Struktura třídy GeometricShapes začíná s velice jednoduchým rozhraním, IGeometricShape, které uvádí metody běžné pro všechny tři typy tvarů: package com.example.programmingas3.geometricshapes { public interface IGeometricShape { function getArea():Number; function describe():String; } }
Rozhraní definuje dvě metody: metodu getArea(), která vypočítává a vrací oblast tvaru a metodu describe(), která sestavuje textový popis vlastností tvaru. Také je vhodné znát vzdálenost kolem obvodu každého tvaru. Obvod kruhu je vypočten jedinečným způsobem, takže se chování liší od chování trojúhelníku nebo čtverce. Přesto mezi trojúhelníky, čtverci a jinými mnohoúhelníky existuje dostatečná podobnost a je tedy dobré definovat novou třídu rozhraní pouze pro ně: IPolygon. Rozhraní IPolygon je, jak je ukázáno níže, také spíše jednoduché: package com.example.programmingas3.geometricshapes { public interface IPolygon extends IGeometricShape { function getPerimeter():Number; function getSumOfAngles():Number; } }
Poslední aktualizace 12.5.2011
118
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Objektově orientované programování v jazyce ActionScript
Toto rozhraní definuje dvě metody společné pro všechny mnohoúhelníky: metodu getPerimeter(), která měří kombinovanou vzdálenost všech stran a metodu getSumOfAngles(), která sčítá všechny vnitřní úhly. Rozhraní IPolygon rozšiřuje rozhraní IGeometricShape, což znamená, že jakákoliv třída, která implementuje rozhraní IPolygon, musí deklarovat všechny čtyři metody - dvě z rozhraní IGeometricShape a dvě z rozhraní IPolygon.
Definice tříd tvaru Jakmile pochopíte metody společné pro každý typ tvaru, můžete definovat samotné třídy tvarů. Co se týče počtu metod, které potřebujete implementovat, je nejjednodušší třídou třída Circle: package com.example.programmingas3.geometricshapes { public class Circle implements IGeometricShape { public var diameter:Number; public function Circle(diam:Number = 100):void { this.diameter = diam; } public function getArea():Number { // The formula is Pi * radius * radius. var radius:Number = diameter / 2; return Math.PI * radius * radius; } public function getCircumference():Number { // The formula is Pi * diameter. return Math.PI * diameter; } public function describe():String { var desc:String = "This shape is a Circle.\n"; desc += "Its diameter is " + diameter + " pixels.\n"; desc += "Its area is " + getArea() + ".\n"; desc += "Its circumference is " + getCircumference() + ".\n"; return desc; } } }
Třída Circle implementuje rozhraní IGeometricShape, takže musí poskytnout kód pro metodu getArea() i metodu describe(). Dále definuje metodu getCircumference(), která je jedinečná pro třídu Circle. Třída Circle také deklaruje vlastnost diameter, kterou lze najít v jiných třídách mnohoúhelníků. Druhé dva typy tvarů, čtverce a jednostranné trojúhelníky, mají společné i jiné věci: oba mají stejně dlouhé strany a existují společné vzorce, které můžete použít pro výpočet obvodu a součtu vnitřních úhlů obou tvarů. Tyto společné vzorce defacto platí pro jakékoliv jiné pravidelné mnohoúhelníky, jež budou definovány i v budoucnosti.
Poslední aktualizace 12.5.2011
119
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Objektově orientované programování v jazyce ActionScript
Třída RegularPolygon je nadřazenou třídou pro třídu Square i třídu EquilateralTriangle. Nadřazená třída vám umožňuje definovat běžné metody na stejném místě, takže je nemusíte definovat zvlášť v každé podtřídě. Zde je kód pro třídu RegularPolygon: package com.example.programmingas3.geometricshapes { public class RegularPolygon implements IPolygon { public var numSides:int; public var sideLength:Number; public function RegularPolygon(len:Number = 100, sides:int = 3):void { this.sideLength = len; this.numSides = sides; } public function getArea():Number { // This method should be overridden in subclasses. return 0; } public function getPerimeter():Number { return sideLength * numSides; } public function getSumOfAngles():Number { if (numSides >= 3) { return ((numSides - 2) * 180); } else { return 0; } } public function describe():String { var desc:String = "Each side is " + sideLength + " pixels long.\n"; desc += "Its area is " + getArea() + " pixels square.\n"; desc += "Its perimeter is " + getPerimeter() + " pixels long.\n"; desc += "The sum of all interior angles in this shape is " + getSumOfAngles() + " degrees.\n"; return desc; } } }
Nejprve třída RegularPolygon deklaruje dvě vlastnosti, které jsou společné pro všechny pravidelné mnohoúhelníky: délka každé strany (vlastnost sideLength) a počet stran (vlastnost numSides). Třída RegularPolygon implementuje rozhraní IPolygon a deklaruje všechny čtyři metody rozhraní IPolygon. Tato třída implementuje dvě z nich - metodu getPerimeter() a metodu getSumOfAngles() - pomocí společných vzorců.
Poslední aktualizace 12.5.2011
120
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Objektově orientované programování v jazyce ActionScript
Protože se vzorec pro metodu getArea() liší tvar od tvaru, nemůže verze metody základní třídy zahrnovat společnou logiku, která může být zděděna metodami podtřídy. Místo toho jednoduše vrátí výchozí hodnotu 0 udávající, že daná oblast nebyla vypočtena. Pro správný výpočet oblasti každého tvaru musí podtřídy třídy RegularPolygon potlačit samotnou metodu getArea(). Následující kód pro třídu EquilateralTriangle ukazuje, jak je metoda getArea() potlačena: package com.example.programmingas3.geometricshapes { public class EquilateralTriangle extends RegularPolygon { public function EquilateralTriangle(len:Number = 100):void { super(len, 3); } public override function getArea():Number { // The formula is ((sideLength squared) * (square root of 3)) / 4. return ( (this.sideLength * this.sideLength) * Math.sqrt(3) ) / 4; } public override function describe():String { /* starts with the name of the shape, then delegates the rest of the description work to the RegularPolygon superclass */ var desc:String = "This shape is an equilateral Triangle.\n"; desc += super.describe(); return desc; } } }
Klíčové slovo override udává, že metoda EquilateralTriangle.getArea() záměrně potlačí metodu getArea() z nadřazené třídy RegularPolygon. Při vyvolání metoda EquilateralTriangle.getArea() vypočte oblast pomocí vzorce v předcházejícím kódu a kód v metodě RegularPolygon.getArea() nebude nikdy proveden. Naopak třída EquilateralTriangle nedefinuje svou vlastní verzi metody getPerimeter(). Při vyvolání metody EquilateralTriangle.getPerimeter() prochází volání řetězcem dědičnosti a provede kód v metodě getPerimeter() nadřazené třídy RegularPolygon.
Konstruktor EquilateralTriangle() používá příkaz super() pro explicitní vyvolání konstruktoru RegularPolygon() ze své nadřazené třídy. Pokud by konstruktory měly stejnou množinu parametrů, mohli byste úplně vypustit konstruktor EquilateralTriangle() a konstruktor RegularPolygon() by byl proveden místo něj. Nicméně konstruktor RegularPolygon() potřebuje parametr navíc, numSides. Proto konstruktor EquilateralTriangle() vyvolá metodu super(len, 3), která projde podél vstupního parametru len a hodnoty 3, která určuje, že daný trojúhelník bude mít 3 strany. Metoda describe() rovněž používá příkaz super(), avšak odlišným způsobem. Používá jej k vyvolání verze metody describe() nadřazené třídy RegularPolygon. Metoda EquilateralTriangle.describe() nejprve nastaví proměnnou řetězce desc pro příkaz ohledně typu tvaru. Poté získá výsledky metody RegularPolygon.describe() vyvoláním super.describe()a připíše výsledek k řetězci desc. Třídu Square zde není popsána podrobně, je však podobná třídě EquilateralTriangle a poskytuje konstruktor a své vlastní implementace metod getArea() a describe().
Poslední aktualizace 12.5.2011
121
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Objektově orientované programování v jazyce ActionScript
Polymorfismus a metoda rodiny Množina třídy, která využívá rozhraní a dědičnost, může být použita mnoha zajímavými způsoby. Například všechny zatím popsané třídy tvaru buď implementují rozhraní IGeometricShape nebo rozšiřují nadřazenou třídu, která provádí implementaci. Takže pokud definujete proměnou jako instanci třídy IGeometricShape, nemusíte vědět, zda se vlastně jedná o instanci třídy Circle nebo Square, aby došlo k vyvolání její metody describe(). Následující kód ukazuje způsob funkce: var myShape:IGeometricShape = new Circle(100); trace(myShape.describe());
Při vyvolání myShape.describe() dojde k provedení metody Circle.describe(), protože ačkoliv je proměnná definována jako instance rozhraní IGeometricShape, třída Circle je její základní třídou. Tento příklad ukazuje princip polymorfismu v akci: přesně to samé volání metody bude mít za následek provedení různého kódu, a to v závislosti na třídě objektu, jehož metoda je vyvolávána. Aplikace GeometricShapes použije tento typ polymorfismu založeného na rozhraní pomocí zjednodušené verze designového vzoru známé jako metoda rodiny. Pojem produkční metoda označuje funkci, která vrací objekt, jehož základní typ dat nebo obsah se může lišit v závislosti na kontextu. Zde uvedená třída GeometricShapeFactory definuje metodu rodiny pojmenovanou createShape(): package com.example.programmingas3.geometricshapes { public class GeometricShapeFactory { public static var currentShape:IGeometricShape; public static function createShape(shapeName:String, len:Number):IGeometricShape { switch (shapeName) { case "Triangle": return new EquilateralTriangle(len); case "Square": return new Square(len); case "Circle": return new Circle(len); } return null; } public static function describeShape(shapeType:String, shapeSize:Number):String { GeometricShapeFactory.currentShape = GeometricShapeFactory.createShape(shapeType, shapeSize); return GeometricShapeFactory.currentShape.describe(); } } }
Poslední aktualizace 12.5.2011
122
JAK SE NAUČIT JAZYK ACTIONSCRIPT 3.0 Objektově orientované programování v jazyce ActionScript
Metoda rodiny createShape() umožňuje konstruktorům podtřídy tvaru definovat podrobnosti instancí, které vytvářejí, zatímco vracejí nové objekty jako instance IGeometricShape, takže je aplikace může zpracovat obecnějším způsobem. Metoda describeShape() v předcházejícím příkladě ukazuje, jak může aplikace použít metodu rodiny pro získání obecné reference ke specifičtějšímu objektu. Aplikace může získat popis pro nově vytvořený objekt Circle takto: GeometricShapeFactory.describeShape("Circle", 100);
Metoda describeShape() poté vyvolá metodu rodiny createShape() se stejnými parametry a uchová nový objekt kruhu ve statické proměnné pojmenované currentShape, která je typem objektu IGeometricShape. Poté je vyvolána metoda describe() na objektu currentShape a dané volání je automaticky vyřešeno pro provedení metody Circle.describe(), která bude mít za následek podrobný popis kruhu.
Vylepšení vzorové aplikace Skutečná váha rozhraní a dědičnosti bude zřejmá, jakmile vylepšíte nebo změníte svou aplikaci. Řekněme, že k této vzorové aplikaci chcete přidat nový tvar, pětiúhelník. Vytvořili byste novou třídu Pentagon, která rozšiřuje třídu RegularPolygon a definuje své vlastní verze metod getArea() a describe(). Poté byste přidali novou volbu pětiúhelníku do vstupního pole v uživatelském rozhraní aplikace. Ale to je vše. Třída Pentagon by automaticky získala funkce metody getPerimeter() a metody getSumOfAngles() z třídy RegularPolygon prostřednictvím dědičnosti. Protože dědí ze třídy, která implementuje rozhraní IGeometricShape, může být s instancí Pentagon zacházeno také jako s instancí IGeometricShape. To znamená, že pro přidání nového typu tvaru nepotřebujete změnit metodu podpisu žádné z metod ve třídě GeometricShapeFactory (a následně také nemusíte změnit žádný z kódů, která třída GeometricShapeFactory používá). Můžete si přát přidat třídu Pentagon k příkladu geometrických tvarů jako cvičení a zjistit tak, jak mohou rozhraní a dědičnost ulehčit pracovní zatížení přidání nových funkcí do aplikace.
Poslední aktualizace 12.5.2011