TypeScript 類

2019-01-29 15:50 更新

TypeScript是面向對象的JavaScript。TypeScript支持面向對象的編程功能,如類,接口等。OOP中的類是用于創(chuàng)建對象的藍圖。類封裝了對象的數據。Typescript為這個名為類的概念提供內置支持。JavaScript ES5或更早版本不支持類。TypeScript會從ES6獲得此功能。

創(chuàng)建類

使用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)建實例對象

要創(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

TypeScript ─ 類的繼承和方法重寫

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

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關鍵字

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運算符

如果對象屬于指定類型,則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
以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號