TypeScript是面向對象的JavaScript。TypeScript支持面向對象的編程功能,如類,接口等。OOP中的類是用于創(chuàng)建對象的藍圖。類封裝了對象的數據。Typescript為這個名為類的概念提供內置支持。JavaScript ES5或更早版本不支持類。TypeScript會從ES6獲得此功能。
使用class關鍵字的TypeScript聲明一個類。語法如下所示:
class class_name { //class scope }
class關鍵字后跟類名。在命名類時必須考慮標識符的規(guī)則。
一個類定義可以包括以下內容:
字段 - 字段是在類中聲明的任何變量。字段表示與對象有關的數據
構造函數 - 負責為類的對象分配內存
函數 - 函數表示對象可以采取的操作。它們有時也被稱為方法。
這些組件放在一起稱為該類的數據成員
考慮TypeScript中的Person類。
class Person { }
在編譯時,它會生成以下JavaScript代碼:
//Generated by typescript 1.8.10 var Person = (function () { function Person() { } return Person; }());
class Car { //field engine:string; //constructor constructor(engine:string) { this.engine = engine } //function disp():void { console.log("Engine is : "+this.engine) } }
本示例聲明一個類Car。該類有一個名為engine的字段。同時,聲明字段時不使用var關鍵字。上面的例子聲明為類的構造函數。
構造函數是類的特殊函數,負責初始化類的變量。TypeScript使用constructor關鍵字定義構造函數。構造函數是一個函數,因此可以參數化。
this關鍵字是引用類的當前實例。這里,參數名稱和類字段的名稱是相同的。因此,為了避免歧義,類的字段以this關鍵字為前綴。
disp()是一個簡單的函數定義。注意,此處不使用function關鍵字。
在編譯時,它會生成以下JavaScript代碼:
//Generated by typescript 1.8.10 var Car = (function () { //constructor function Car(engine) { this.engine = engine; } //function Car.prototype.disp = function () { console.log("Engine is : " + this.engine); }; return Car; }());
要創(chuàng)建類的實例,請使用new關鍵字后跟類名。語法如下所示:
var object_name = new class_name([ arguments ])
new關鍵字負責實例化。
表達式的右邊調用構造函數。如果參數化,構造函數應該傳遞值。
var obj = new Car("Engine 1")
可以通過對象訪問類的屬性和函數。使用“.”點表示法(稱為句點)訪問類的數據成員。
//accessing an attribute obj.field_name //accessing a function obj.function_name()
class Car { //field engine:string; //constructor constructor(engine:string) { this.engine = engine } //function disp():void { console.log("Function displays Engine is : "+this.engine) } } //create an object var obj = new Car("XXSY1") //access the field console.log("Reading attribute value Engine as : "+obj.engine) //access the function obj.disp()
在編譯時,它會生成以下JavaScript代碼。
//Generated by typescript 1.8.10 var Car = (function () { //constructor function Car(engine) { this.engine = engine; } //function Car.prototype.disp = function () { console.log("Function displays Engine is : " + this.engine); }; return Car; }()); //create an object var obj = new Car("XXSY1"); //access the field console.log("Reading attribute value Engine as : " + obj.engine); //access the function obj.disp();
上面的代碼的輸出如下:
Reading attribute value Engine as : XXSY1 Function displays Engine is : XXSY1
TypeScript支持繼承的概念。繼承是一種程序從現(xiàn)有的類中創(chuàng)建新類的能力。擴展為創(chuàng)建較新類的類稱為父類/超類。新創(chuàng)建的類被稱為子類。
一個類使用“extends”關鍵字從另一個類繼承。子類繼承父類的私有成員和構造函數之外的所有屬性和方法。
class child_class_name extends parent_class_name
然而,TypeScript不支持多重繼承。
class Shape { Area:number constructor(a:number) { this.Area = a } } class Circle extends Shape { disp():void { console.log("Area of the circle: "+this.Area) } } var obj = new Circle(223); obj.disp()
在編譯時,它會生成以下JavaScript代碼:
//Generated by typescript 1.8.10 var __extends = (this && this.__extends) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; var Shape = (function () { function Shape(a) { this.Area = a; } return Shape; }()); var Circle = (function (_super) { __extends(Circle, _super); function Circle() { _super.apply(this, arguments); } Circle.prototype.disp = function () { console.log("Area of the circle: " + this.Area); }; return Circle; }(Shape)); var obj = new Circle(223); obj.disp();
上面的代碼的輸出如下:
Area of the Circle: 223
上面的例子聲明了一個類Shape。該類由Circle類擴展。既然是類之間的繼承關系,因此子類(即Car類)獲得對其父類屬性(即area)的隱式訪問。
繼承可以歸類為:
單個 - 每個類最多可以從一個父類擴展
多個 - 一個類可以從多個類繼承。TypeScript不支持多重繼承。
多級的 - 下面的例子顯示多級繼承的工作原理。
class Root { str:string; } class Child extends Root {} class Leaf extends Child {} //indirectly inherits from Root by virtue of inheritance var obj = new Leaf(); obj.str ="hello" console.log(obj.str)
類Leaf通過多級繼承從Root類和Child類派生屬性。
在編譯時,它會生成以下JavaScript代碼:
//Generated by typescript 1.8.10 var __extends = (this && this.__extends) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; var Root = (function () { function Root() { } return Root; }()); var Child = (function (_super) { __extends(Child, _super); function Child() { _super.apply(this, arguments); } return Child; }(Root)); var Leaf = (function (_super) { __extends(Leaf, _super); function Leaf() { _super.apply(this, arguments); } return Leaf; }(Child)); var obj = new Leaf(); obj.str = "hello"; console.log(obj.str);
它的輸出如下:
hello
方法重寫是由子類重新定義父類方法的機制。 以下示例說明了相同的情況:
class PrinterClass { doPrint():void { console.log("doPrint() from Parent called…") } } class StringPrinter extends PrinterClass { doPrint():void { super.doPrint() console.log("doPrint() is printing a string…") } } var obj = new StringPrinter() obj.doPrint()
super關鍵字用來引用類的直接父級。關鍵字可用于引用變量,屬性或方法的超類版本。第13行調用的doWork()函數的超類版本。
在編譯時,它會生成以下JavaScript代碼。
//Generated by typescript 1.8.10 var __extends = (this && this.__extends) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; var PrinterClass = (function () { function PrinterClass() { } PrinterClass.prototype.doPrint = function () { console.log("doPrint() from Parent called…"); }; return PrinterClass; }()); var StringPrinter = (function (_super) { __extends(StringPrinter, _super); function StringPrinter() { _super.apply(this, arguments); } StringPrinter.prototype.doPrint = function () { _super.prototype.doPrint.call(this); console.log("doPrint() is printing a string…"); }; return StringPrinter; }(PrinterClass)); var obj = new StringPrinter(); obj.doPrint();
上面的代碼的輸出如下:
doPrint() from Parent called… doPrint() is printing a string…
static關鍵字可以應用于類的數據成員。靜態(tài)變量保留其值,直到程序完成執(zhí)行。靜態(tài)成員由類名引用。
class StaticMem { static num:number; static disp():void { console.log("The value of num is"+ StaticMem.num) } } StaticMem.num = 12 // initialize the static variable StaticMem.disp() // invoke the static method
在編譯時,它會生成以下JavaScript代碼。
//Generated by typescript 1.8.10 var StaticMem = (function () { function StaticMem() { } StaticMem.disp = function () { console.log("The value of num is" + StaticMem.num); }; return StaticMem; }()); StaticMem.num = 12; // initialize the static variable StaticMem.disp(); // invoke the static method
上面的代碼的輸出如下:
The value of num is 12
如果對象屬于指定類型,則instanceof運算符返回true。
class Person{ } var obj = new Person() var isPerson = obj instanceof Person; console.log(" obj is an instance of Person " + isPerson);
在編譯時,它會生成以下JavaScript代碼。
//Generated by typescript 1.8.10 var Person = (function () { function Person() { } return Person; }()); var obj = new Person(); var isPerson = obj instanceof Person; console.log(" obj is an instance of Person " + isPerson);
上面的代碼的輸出如下:
obj is an instance of Person True
類可以控制其數據成員的其他類成員的可見性。此功能稱為Data Hiding(數據隱藏
)或Encapsulation(封裝)。
面向對象使用訪問修飾符或訪問說明符的概念來實現(xiàn)封裝的概念。訪問說明符/修飾符定義類的數據成員在其定義類之外的可見性。
通過TypeScript支持的訪問修飾符是 -
序號 | 訪問說明符和說明 |
---|---|
1 | public 公共的數據成員具有普遍的可訪問性。默認情況下,類中的數據成員是公共的。 |
2 | private 私有數據成員只能在定義這些成員的類中訪問。如果外部類成員嘗試訪問私有成員,則編譯器會引發(fā)錯誤。 |
3 | protected 受保護的數據成員可以由與前者相同的類中的成員訪問,也可以由子類的成員訪問。 |
現(xiàn)在讓我們舉個例子來看看數據隱藏如何工作:
class Encapsulate { str:string = "hello" private str2:string = "world" } var obj = new Encapsulate() console.log(obj.str) //accessible console.log(obj.str2) //compilation Error as str2 is private
該類有兩個字符串屬性,str1和str2,分別是public和private成員。該類被實例化。該示例返回一個編譯時錯誤,因為私有屬性str2在聲明它的類之外訪問。
類還可以實現(xiàn)接口。
interface ILoan { interest:number } class AgriLoan implements ILoan { interest:number rebate:number constructor(interest:number,rebate:number) { this.interest = interest this.rebate = rebate } } var obj = new AgriLoan(10,1) console.log("Interest is : "+obj.interest+" Rebate is : "+obj.rebate )
AgriLoan類實現(xiàn)了Loan接口。因此,它現(xiàn)在綁定在類上以包含interest屬性作為其成員。
在編譯時,它會生成以下JavaScript代碼。
//Generated by typescript 1.8.10 var AgriLoan = (function () { function AgriLoan(interest, rebate) { this.interest = interest; this.rebate = rebate; } return AgriLoan; }()); var obj = new AgriLoan(10, 1); console.log("Interest is : " + obj.interest + " Rebate is : " + obj.rebate);
上面的代碼的輸出如下:
Interest is : 10 Rebate is : 1
更多建議: