A TypeScript programozási nyelv

Objektum-orientált programozás

Osztályok

TypeScript támogatja az objektum-orientáltságot, ezért lehetőség van osztályok definiálására is. Szintaxis nagyon hasonlít a Java-ban lévő szintaxissal.

class [osztály név] extends [ősosztály] implements [interfészek] { [osztály törzse] }

Mivel a Javascript objektum-orientált nyelv, ezért a TypeScript fordítója az osztályokat, Javascript objektummá generálja. Példányosítani a már megszokott new operátorral lehet.

class A { /* ... osztály törzse ... */ } var a : A = new A();

Lehetőség van tulajdonságok (property), statikus tagok (static member) használatára. Jelenleg azonban nem támogatja a beágyazott osztályokat (nested class).

class Person { private _name: string; //getter metódus public get name() { return this._name; } //setter metódus public set name(value: string) { this._name = value; } }

Az osztálytagoknak kétféle láthatóságot lehet beállítani: public, private. A statikus tagok csak publikusak lehetnek (meglehet őket jelölni privátként is, de a fordító figyelmenkívül hagyja).
A 9.0-s verziótól kötelezően meg kell adni a statikus adattagok láthatóságát. A metódusokat felül lehet definiálni a leszármazott osztályban, de a függvénytúlterhelés nem megengedett. Konstruktorok láthatósága mindig public.
A 9.0-s verziótól a felüldefiniált függvény deklarációját közvetlenül követnie kell az implementációjának.

Konstruktorok

TypeScript-ben az osztálynak csak egy konstruktora lehet. Minden konstruktornak kötelezően publikus láthatósága kell, hogy legyen. Ha az osztálynak nem adjuk meg explicit a konstruktorát és nincs ősosztálya, akkor automatikusan létrejön egy paraméternélküli konstruktor. Ha egy megadtunk egy ősosztályt és neki van definiálva konstruktor, akkor azt a leszármazott automatikusan örökli.
Lehetőség van a leszármazottban felüldefiniálni a konstruktort, de akkor kötelezően meg kell hívni a super(paraméterek); parancsot az első sorban.

class Identifier ClassHeritage { //Konstruktor szintaxisa constructor (ParameterList) { Body } }

Osztály tulajdonságok (property)

Lehetőség van getter/setter metódusok megadására is. Használatuk megegyezik a C#-ban megismerttel. A setter metódusnak mindig void-al kell visszatérnie és pontosan egy argumentuma lehet. Statikus (static) property-ket is létrehozhatunk.

class Identifier { private _property: Type; public get property(): Type { return _property; } public set property(value: Type) { this._property = value; } }

Érdekesség, hogy lehetőség van automatikus tulajdonságokat is megadni a konstruktorban. Ilyenkor public kulcsszóval kell megjelölni az argumentumokat.

class Point { //public x: number; public y: number; constructor(public x: number, public y: number) { //this.x = x; //this.y = y; } } var p: Point = new Point(10, 10); console.log(p.x, p.y);

Példány és statikus adattagok

Az adattagok lehetnek példány adattagok és statikus adattagok. A példány adattagok az osztály típus adattagjai és és összekapcsolható a példány típussal. A konstruktoron és a példány tagfüggvényeken belül a „this” típusa az osztály példány típusa. A statikus tagokat a „static” kulcsszóval deklaráljuk és a konstruktor függvény típusának tagjai. A statikus tagfüggvényekben a „this” típusa a konstruktor függvény típusa, kivéve a kostrukt szignatúrában.

Öröklődés

TypeScript nem támogatja a többszörös öröklődést. Egy osztálynak csak egy ősosztálya lehet, de korlátlan interfészt implementálhat. Az öröklődés szintaxisa hasonlít a Java nyelv szintaxisával. Az ősosztályt az extends kulcsszó után kell megadni, míg az implementált interfészeket az implements kulcsszó vezeti be.
Az örökölt metódusokat felül lehet definiálni a leszármazott osztályban, de a függvények túlterhelése nem megengedett.

class Identifier extends BaseClass implements Interface { ClassBody }

Interfészek

Lehetőség van interfészek definiálására is. Nincs futásidejű reprezentációja (azaz Javascript-ben nem generálódik számára semmi se), lényegében csak egy megszorítás a változók típusának "alakjára". Ennek következménye, hogy csak fordítási időben dob hibát.

interface Identifier [extends InterfaceNameList] { InterfaceBody }

Minden tagjának kötelezően publikusnak kell lennie, de a tőle örökölt mezők, függvények lehetnek privátok az osztályban. Érdekesség, hogy két interfészt a fordító strukturálisan hasonlít össze, így nem szükséges explicit deklarálni egy osztályt, hogy ténylegesen is tudjuk használni.

interface IPerson { name: string; age: number; } var person: IPerson = { name: "Gipsz Jakab", age: 34 }; var person2: IPerson = { name: "Gipsz Jakab" }; //fordítási hiba: hiányzik az age

A C#-ban vagy Java-ban megismert interface-ektől eltérően, a felhasználó ? operátorral megjelölheti a mezőket, metódusokat, amiknek a használata opcionális lesz.

interface IPerson { name: string; age?: number; } var person: IPerson = { name: "Gipsz Jakab" }; //mostmár jó, mivel az age opcionális

Interfészek kiterjesztése osztályokra

Amikor egy interfész típus kiterjeszt egy osztály típust, örökli annak tagjait, de nem örökli az implementációkat. Ez olyan, mintha az interfész deklarálná az osztály összes tagját anélkül, hogy implementálná azokat. Az interface-ek öröklik még az ősosztály privát tagjait is. Ha egy privát tagot tartalmazó osztály az ős típusa az interface típusnak, akkor csak ez az osztály vagy ennek egy leszármazott osztálya implementálhatja ezt az interface típust. Például:

class Control { private state: any; } interface SelectableControl extends Control { select(): void; } class Button extends Control { select() { } } class TextBox extends Control { select() { } } class Image extends Control { } class Location { select() { } }

A fenti példában a „SelectableControl” tartalmazza a Control összes tagját, beleértve a privát „state” tulajdonságot is. Mivel a „state” egy privát adattag, ez csak úgy lehetséges, hogy a „Control” leszármazottjai implementálják a „SelectableControl”-t. Ez azért van, mert csak a „Control” leszármazottainak lesz „state” adattagjuk, ami a közös deklarációból ered, amely szükséges ahhoz, hogy a privát adattagok összeegyeztethetőek legyenek. A „Control” osztályban elérhető a „state” privát adattag a „SelectableControl” egy példányán keresztül. Valójában a „SelectabelControl” úgy működik, mint egy „Control”, amely tudja, hogy van egy „select” metódusa. A „Button” és a „TextBox” osztályok altípusai a „SelectableControlnak”, mivel mindketten örökölnek a „Control” osztálytól és van „select” metódusuk. Azonban az „Image” és a „Location” osztályok nem altípusai a „SelectableControl”-nak.