Typescript的interface、class和abstract class
阿新 • • 發佈:2020-06-21
interface,class,和abstract class這3個概念,既有聯絡,又有區別,本文嘗試著結合官方文件來闡述這三者之間的關係。
### 1. [Declaration Merging](https://www.staging-typescript.org/docs/handbook/declaration-merging.html)
|Declaration Type| Namespace| Type| Value|
| ----|----|----|-----|
|Namespace| X| | X|
|Class|| X| X|
|Enum| |X| X|
|Interface|| X||
|Type Alias|| |X||
|Function||| X|
|Variable |||X|
首先我們來講一下上面這張表格,當我們第一列的關鍵字進行宣告時,我們在做什麼。
```js
namespace job {
haircut(): void;
}
class Man{
name: string;
}
let imgss = new Man();
enum Color {red, blue, yellow}
interface dogfood {
brand: string;
price: number
}
type event = 'mouse' | 'keyboard';
function foo(){}
let a = 2;
var b = {};
const c = null;
```
namespace用來宣告一個名稱空間,比較著名的名稱空間有lodash,裡面有一堆工具函式,統統放在一個叫_的namespace裡面,同時你也可以`let $ = _`;所以namespace也聲明瞭一個值。
class聲明瞭一個值,也聲明瞭一種型別,你可以把Man賦值給一個變數,所以class是一種值,也可以說imgss是一個Man(型別),此時Man承擔了一種型別的角色。
enum聲明瞭一個值,也聲明瞭一種型別。我們說red是一種Color,Color在這裡承擔型別的角色,也可以把Color賦值給一個變數
interface聲明瞭一種型別,但是你不能把dogfood賦值給某個變數,否則你會得到一個報錯``dogfood' only refers to a type, but is being used as a value here`
其他function,let,var,const都在宣告一個值,你 不能說xxx是一個a,或者xxx是一個foo,不能把值當成型別使用。
### 2. interface和class
我們知道,不算symbol,js中有6種基本型別,number,string,boolean,null, undefined, object。但是隻依靠這幾種型別,來描述某個函式需要傳什麼樣的引數,是遠遠不夠的,這也是interface的使命--描述一個值(value)的形狀(type)。
現在我們來看class,class首先也具有interface的能力,描述一個形狀,或者說代表一種型別。此外class還提供了實現,也就是說可以被例項化;
所以class可以implements interface:
```js
interface ManLike {
speak(): void;
leg: number;
hand: number;
}
class Human implements ManLike {
leg: number = 2;
hand: number = 2;
speak() {
console.log('i can speak');
}
}
```
而interface可以extends class,此時的class承擔型別的角色
```js
interface Chinese extends Human {
country: string;
}
```
那麼interface能不能extends enum或者type alias呢,這兩個兄弟也聲明瞭type啊,答案是不行的,官方報錯的資訊:
```
An interface can only extend an object type or intersection of object types with statically known members.
```
### 3. class和abstract class
class和abstract class的區別主要是abstract class不能被例項化:
```js
abstract Human {
name: string;
abstract lang(): void;
toString() {
return ``
}
}
new Human // Cannot create an instance of an abstract class.
```
### 4. interface和abstract class
兩者都不能被例項化,但是abstract class 也可以被賦值給變數。
interface 裡面不能有方法的實現,abstract class 可以提供部分的方法實現,這些方法可以被子類