Třídy
Obsah
Základy jsou popsány dříve
Základní principy byly položeny již v AS2. Většina z nich funguje i ve verzi 3, některé s menšími obměnami. Pro informace o třídách AS2 se mrkněte do předchozí sekce. Tady budu věnovat víc pozornosti novinkám.
Jmenná konvence
Při kompilaci hledá kompiler třídy, podle kterých vytvoří prototypy v programu. Aby je nalezl, je stanovena jejich jmenná konvence. Pravidla jsou stejná jako v AS2:
Název třídy je shodný s názvem souboru
Třída
enginebude uložena v souboruengine.as.Soubor s třídou je v kmenovém adresáři animace
Nebo v jednom s nastavených adresářů v Publish Settings.

Názvy balíčků tříd odpovídají názvům vnořených adresářů
Třída
engine, která je uvnitř balíčkucommon.utilsbude v souboru./common/utils/engine.as.V každém souboru může být jen jedna veřejná třída
Co je veřejná třída se dozvíte dále. Je to vcelku logické. Pokud má kompiler hledat třídu podle jména souboru, může jednomu jménu souboru odpovídat jen jeden prvek v něm obsažený.
Balíček (package)
Už v AS2 šly třídy sdružovat do složek, balíčků. Pokud se podíváte do předdefinovaných tříd Flashe, zjistíte, že v AS3 už jsou všechny rozděleny do balíčků. Kromě zpřehlednění to brání také jmenným kolizím. Můžete mít například obyčejné tlačítko flash.display.Button a zároveň formulářové tlačítko fl.controls.Button.
Zatímco v AS2 byl název balíčku součástí jména třídy, v AS3 se odsunul trochu přehledněji do bloku package.
package common.utils { class engine { function engine(){ trace('baf'); } } }
Blok package je povinný. I pokud třída není součástí balíčku.
Import
Pokud chceme použít třídu z jiného než aktuálního balíčku, je třeba ji napsat s kompletním názvem.
var promenna = new common.utils.engine(); // baf
Častěji se ale používá příkaz import.
import common.utils.engine; var promenna = new engine(); // baf
Kvalitnější editory se o definování importů starají samy, ve Flashi asi často sáhnete po zbrani posledního soudu:
import common.utils.*; // vloží všechny třídy z common.utils
Doporučuje se používat unikátní názvy balíčků. U větších projektů předejdete jmenným kolizím.
Jeden z doporučených způsobů je použít (obráceně) jméno domény, kde bude flash umístěn.
Například cz.jakpsatweb.flash.common.utils.engine
Mezi cílovou doménou a názvy tříd ale samozřejmě není žádná vazba - je to jen konvence.
Dostupnost prvků
Stejně jako v AS2, i zde lze definovat dostupnost jednotlivých prvků třídy. Nově také i samotné třídě.
Veřejný (
public)Přístupný odkudkoliv.
Privátní (
private)Přístupný jen v rámci své třídy.
Chráněný (
protected)Přístupný jen v rámci své třídy a z jejich potomků.
AS2 měl atribut
privatetyto vlastnosti aprotectedneexistoval.Interní (
internal)Přístupný jen v rámci svého balíčku.
Dostupnost tříd
I samotné třídy mohou mít definovánu úroveň dostupnosti - public pro běžnou třídu a internal pro třídu dostupnou jen v rámci aktuálního balíčku.
Pokud neuvedete dostupnost třídy, bude implicitně internal nikoliv public.
Pomocná třída souboru
Soubor musí obsahovat právě jednu externě dostupnou třídu. Kromě toho ale může obsahovat pomocné třídy, dostupné jen z tohoto souboru.
// soubor ./common/utils/engine.as package common.utils { public class engine { function engine(){ var pomocna = new auxiliary(); } } } class auxiliary(){ function auxiliary(){ } }
Všimněte si, že pomocná třída auxiliary není uvnitř balíčku. Je dostupná jen a pouze z tohoto souboru.
Přepsání prvku třídy (override)
Potomek třídy může přepsat některé prvky svého rodiče.
package common.utils { public class engine { public function engine(){ } protected function start(){ trace('vrrrrr'); } } }
package common.utils { public class jet extends engine { function jet(){ } override protected function start(){ trace('ffffff'); } } }
Je třeba dodržet stejné vlastnosti i vstupní a výstupní datové typy přepisovaného prvku
Pokud je původní metoda chráněná, její přepsaná varianta musí být také chráněná.
Privátní prvky logicky nejdou přepisovat.
Konečný prvek (final)
Prvek označený jako final nelze přepsat.
package common.utils { public class engine { public function engine(){} final protected function start(){ trace('vrrrrr'); } } }
package common.utils { public class jet extends engine { function jet(){} override protected function start(){ trace('ffffff'); } } }
1025: Cannot redefine a final method.
Pokud označíte třídu jako final, nebude rozšířitelná.
Jmenný prostor (namespace)
Pro fajnové šmekry hrubšího zrna a Flashové aplikace větší než velké, je možné prvky tříd zahrnout do obecné množiny - do jmenného prostoru. Ten se může rozprostírat i přes hranice tříd a balíčků - vytvářet tak jakýsi průnik prvků společných vlastností.
Jmenný prostor lze také chápat jako vlastní variantu přístupnosti prvků objektu.
Vytvoření jmenného prostoru
Jmenný prostor se vytváří stejně jako třída, také platí stejná pravidla pro jméno a umístění jeho souboru.
package common.utils { public namespace utilities = 'http://flash.jakpsatweb.cz/utilities/'; }
Adresa jmenného prostoru je dobrovolná.
Konvence použití URL je převzata z XML a má sloužit jen k unikátnímu odlišení jmenného prostoru. Kompiler adresu nekontroluje, může místo ní být cokoliv nebo také nic.
Tento předpis musí být v souboru ./common/utils/utilities.as.
Pozor na dostupnost jmenného prostoru. Platí stejná pravidla jako u tříd - public pro volně dostupný, internal pro interní v rámci balíčku.
Použití jmenného prostoru
Název jmenného prostoru se uvádí před definici metody či vlastnosti.
package common.factory { import common.utils.utilities; public class assembly { public function assembly(){} utilities function gearbox(){ trace('utilities::gearbox'); } } }
Pokud použijeme jmenný prostor z jiného balíčku, nesmíme zapomenout na import.
Prvky jmenného prostoru nejsou automaticky dostupné
Jak už název napovídá, je to jmenný prostor, prostor s jiným jménem. Prvky z jiného NS nejsou ve jmenné kolizi s běžnými prvky třídy. Naše třída tak může obsahovat více metod gearbox.
Prvek z jiného jmenného prostoru zavoláme trochu odlišnou syntaxí.
objekt.jmennyprostor::prvek;
package common.factory { import common.utils.utilities; public class assembly { public function assembly(){ this.gearbox(); this.utilities::gearbox(); } utilities function gearbox(){ trace('utilities::gearbox'); } public function gearbox(){ trace('gearbox'); } } }
import common.factory.assembly; var objekt:assembly = new assembly(); // gearbox // utilities::gearbox
Implicitní jmenný prostor (use namespace)
Direktiva use namespace funguje podobně jako import. Říká, že mají být všechny volané prvky hledány také v uvedeném jmenném prostoru.
package common.factory { import common.utils.utilities; use namespace utilities; public class assembly { public function assembly(){ this.gearbox(); // utilities::gearbox } utilities function gearbox(){ trace('utilities::gearbox'); } } }
Také názvy public, private a protected vlastně označují (předdefinované) jmenné prostory. Například zápis this.public::gearbox() by byl zcela platný.
Proxy (flash.utils.Proxy)
Může se stát, že budeme chtít ve své třídě zachytit použití neexistujících prvků nebo sami zpracovat některé přístupy k ní. Na tohle nám getter a setter nepomůže, ten je definován konkrétně. V AS2 existovala metoda __resolve, tu teď nahradila třída Proxy.
Třída, která chce použít Proxy, ji musí rozšiřovat. Pak je jí k dispozici sada metod, zachycující různé typy volání neexistujících prvků:
callProperty(jmeno:*,...zbytek:*):* | zavolání metody |
|---|---|
objekt.neexistujici() | |
getProperty(jmeno:*):* | přečtení vlastnosti |
objekt.neexistujici | |
setProperty(jmeno:*,hodnota:*):void | nastavení vlastnosti |
objekt.neexistujici = 10 | |
hasProperty(jmeno:*):Boolean | kontrola existence vlastnosti |
objekt.hasOwnProperty('neexistujici') | |
deleteProperty(jmeno:*):Boolean | odstranění vlastnosti |
delete objekt.neexistujici | |
getDescendants(jmeno:*):* | získání potomků |
objekt..neexistujici | |
nextName(index:int):String | jméno dalšího prvku pro smyčku for |
for(var jmenodalsiho in objekt) | |
nextNameIndex(index:int):int | index dalšího prvku pro for nebo for each - slouží pro určení počtu iterací těchto smyček |
nextValue(index:int):* | hodnota dalšího prvku pro for each |
for each(var hodnotadalsiho in objekt) |
Na ukázku, vlastní přizpůsobení třídy pro průchod smyčkou for each.
package { import flash.utils.Proxy; import flash.utils.flash_proxy; public class myGroup extends Proxy { private var items:Array = ['a',12,true,-22.6,'x']; override flash_proxy function nextNameIndex(index:int):int { return (index < this.items.length ? index+1 : 0); } override flash_proxy function nextValue(index:int):* { return this.items[index-1]; } } }
Metody třídy Proxy jsou, jak vidíte, ve jmenném prostoru flash_proxy, ten je tedy třeba také importovat.
var group:myGroup = new myGroup(); for each(var item:* in group){ trace(item); }
a 12 true -22.6 x