TypeScript 類

2019-01-29 15:50 更新

TypeScript是面向?qū)ο蟮腏avaScript。TypeScript支持面向?qū)ο蟮木幊坦δ?,如類,接口等。OOP中的類是用于創(chuàng)建對(duì)象的藍(lán)圖。類封裝了對(duì)象的數(shù)據(jù)。Typescript為這個(gè)名為類的概念提供內(nèi)置支持。JavaScript ES5或更早版本不支持類。TypeScript會(huì)從ES6獲得此功能。

創(chuàng)建類

使用class關(guān)鍵字的TypeScript聲明一個(gè)類。語法如下所示:

語法

class class_name { 
   //class scope 
}

class關(guān)鍵字后跟類名。在命名類時(shí)必須考慮標(biāo)識(shí)符的規(guī)則。

一個(gè)類定義可以包括以下內(nèi)容:

  • 字段 - 字段是在類中聲明的任何變量。字段表示與對(duì)象有關(guān)的數(shù)據(jù)

  • 構(gòu)造函數(shù) - 負(fù)責(zé)為類的對(duì)象分配內(nèi)存

  • 函數(shù) - 函數(shù)表示對(duì)象可以采取的操作。它們有時(shí)也被稱為方法。

這些組件放在一起稱為該類的數(shù)據(jù)成員

考慮TypeScript中的Person類。

class Person {
}

在編譯時(shí),它會(huì)生成以下JavaScript代碼:

//Generated by typescript 1.8.10
var Person = (function () {
   function Person() {
   }
   return Person;
}());

例如:聲明一個(gè)類

class Car { 
   //field 
   engine:string; 
 
   //constructor 
   constructor(engine:string) { 
      this.engine = engine 
   }  

   //function 
   disp():void { 
      console.log("Engine is  :   "+this.engine) 
   } 
}

本示例聲明一個(gè)類Car。該類有一個(gè)名為engine的字段。同時(shí),聲明字段時(shí)不使用var關(guān)鍵字。上面的例子聲明為類的構(gòu)造函數(shù)。

構(gòu)造函數(shù)是類的特殊函數(shù),負(fù)責(zé)初始化類的變量。TypeScript使用constructor關(guān)鍵字定義構(gòu)造函數(shù)。構(gòu)造函數(shù)是一個(gè)函數(shù),因此可以參數(shù)化。

this關(guān)鍵字是引用類的當(dāng)前實(shí)例。這里,參數(shù)名稱和類字段的名稱是相同的。因此,為了避免歧義,類的字段以this關(guān)鍵字為前綴。

disp()是一個(gè)簡單的函數(shù)定義。注意,此處不使用function關(guān)鍵字。

在編譯時(shí),它會(huì)生成以下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)建實(shí)例對(duì)象

要?jiǎng)?chuàng)建類的實(shí)例,請使用new關(guān)鍵字后跟類名。語法如下所示:

語法

var object_name = new class_name([ arguments ])
  • new關(guān)鍵字負(fù)責(zé)實(shí)例化。

  • 表達(dá)式的右邊調(diào)用構(gòu)造函數(shù)。如果參數(shù)化,構(gòu)造函數(shù)應(yīng)該傳遞值。

例如:實(shí)例化一個(gè)類

var obj = new Car("Engine 1")

訪問屬性和函數(shù)

可以通過對(duì)象訪問類的屬性和函數(shù)。使用“.”點(diǎn)表示法(稱為句點(diǎn))訪問類的數(shù)據(jù)成員。

//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()

在編譯時(shí),它會(huì)生成以下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)建新類的能力。擴(kuò)展為創(chuàng)建較新類的類稱為父類/超類。新創(chuàng)建的類被稱為子類。

一個(gè)類使用“extends”關(guān)鍵字從另一個(gè)類繼承。子類繼承父類的私有成員和構(gòu)造函數(shù)之外的所有屬性和方法。

語法

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

在編譯時(shí),它會(huì)生成以下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

上面的例子聲明了一個(gè)類Shape。該類由Circle類擴(kuò)展。既然是類之間的繼承關(guān)系,因此子類(即Car類)獲得對(duì)其父類屬性(即area)的隱式訪問。

繼承可以歸類為:

  • 單個(gè) - 每個(gè)類最多可以從一個(gè)父類擴(kuò)展

  • 多個(gè) - 一個(gè)類可以從多個(gè)類繼承。TypeScript不支持多重繼承。

  • 多級(jí)的 - 下面的例子顯示多級(jí)繼承的工作原理。

示例

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通過多級(jí)繼承從Root類和Child類派生屬性。

在編譯時(shí),它會(huì)生成以下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

TypeScript ─ 類的繼承和方法重寫

方法重寫是由子類重新定義父類方法的機(jī)制。 以下示例說明了相同的情況:

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關(guān)鍵字用來引用類的直接父級(jí)。關(guān)鍵字可用于引用變量,屬性或方法的超類版本。第13行調(diào)用的doWork()函數(shù)的超類版本。

在編譯時(shí),它會(huì)生成以下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關(guān)鍵字

static關(guān)鍵字可以應(yīng)用于類的數(shù)據(jù)成員。靜態(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

在編譯時(shí),它會(huì)生成以下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運(yùn)算符

如果對(duì)象屬于指定類型,則instanceof運(yùn)算符返回true。

示例

class Person{ } 
var obj = new Person() 
var isPerson = obj instanceof Person; 
console.log(" obj is an instance of Person " + isPerson);

在編譯時(shí),它會(huì)生成以下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 

數(shù)據(jù)隱藏

類可以控制其數(shù)據(jù)成員的其他類成員的可見性。此功能稱為Data Hiding(數(shù)據(jù)隱藏
)或Encapsulation(封裝)。

面向?qū)ο笫褂迷L問修飾符或訪問說明符的概念來實(shí)現(xiàn)封裝的概念。訪問說明符/修飾符定義類的數(shù)據(jù)成員在其定義類之外的可見性。

通過TypeScript支持的訪問修飾符是 -

序號(hào)訪問說明符和說明
1

public

公共的數(shù)據(jù)成員具有普遍的可訪問性。默認(rèn)情況下,類中的數(shù)據(jù)成員是公共的。

2

private

私有數(shù)據(jù)成員只能在定義這些成員的類中訪問。如果外部類成員嘗試訪問私有成員,則編譯器會(huì)引發(fā)錯(cuò)誤。

3

protected

受保護(hù)的數(shù)據(jù)成員可以由與前者相同的類中的成員訪問,也可以由子類的成員訪問。

示例

現(xiàn)在讓我們舉個(gè)例子來看看數(shù)據(jù)隱藏如何工作:

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

該類有兩個(gè)字符串屬性,str1和str2,分別是public和private成員。該類被實(shí)例化。該示例返回一個(gè)編譯時(shí)錯(cuò)誤,因?yàn)樗接袑傩詓tr2在聲明它的類之外訪問。

類和接口

類還可以實(shí)現(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類實(shí)現(xiàn)了Loan接口。因此,它現(xiàn)在綁定在類上以包含interest屬性作為其成員。

在編譯時(shí),它會(huì)生成以下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
以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)