昨天簡單的介紹了類別的基本用法和繼承概念,今天來繼續探討類別中蠻重要的功能-存取修飾符(Access Modifiers)以及abstract
關鍵字。
什麼是存取修飾符(Access Modifiers) 呢?存取修飾符用來限制類別中的屬性或方法在類別內部或外部被呼叫的權限。目前類別存取修飾符共有三種 - public、private 以及 protected,整理如下:
是否可存取 | public | private | protected |
---|---|---|---|
類別本身 | 可以 | 可以 | 可以 |
繼承的子類別 | 可以 | 不行 | 可以 |
類別的物件實例 | 可以 | 不行 | 不行 |
存取修飾符會標註在類別內部屬性或方法名稱的前面。範例程式碼如下:
class Foo {
constructor(theX: number, theY:number, theZ: number) {
this.x = theX;
this.y = theY;
this.z = theZ
}
public x: number;
private y: number;
protected z: number;
}
// 將類別實例化,創造新物件 foo
let foo = new Foo(2,3,4);
foo.x =1; // OK
foo.y =1; // ERROR (private 修飾符):Property 'y' is private and only accessible within class 'Foo'.
foo.z =1; // ERROR (protected 修飾符): Property 'z' is protected and only accessible within class 'Foo' and its subclasses.
// 繼承的子類別 FooChild
class FooChild extends Foo {
constructor(x:number, y:number, z: number) {
super(x,y,z);
this.x =0; // OK
this.y =0 ; // ERROR(private 修飾符): Property 'y' is private and only accessible within class 'Foo'.
this.z = 0 // OK
this.a = 'hello'
}
private a : string
}
在上方的程式碼中,你會發現標註 public 的屬性或方法在類別本身或外部都可以存取,而標註 private 則只在類別本身內部可存取,protected 的存取限制則介於兩者之間,在繼承的子類別中可以存取,實例化物件則無法存取。
abstract
是 TS 1.6版本加入的新關鍵字,可以加在類別名稱
或類別方法
的前面,用來限制類別的實例化,特性摘要如下:
完整abstract關鍵字的特性說明請參考此說明
範例程式碼如下:
class A {
// ...
}
abstract class B {
foo(): number { return bar(); }
abstract bar() : number;
}
new B; // Error : B為抽象類別,無法創建實例
class C extends B { } // Error : 非抽象類別C繼承抽象類別B,必須實作抽象方法bar()
abstract class D extends B { } // OK
class E extends B { // OK:有實作抽象方法
bar() { return 1; }
類別內的屬性和方法其實分為兩種:實例 ( Instance )和靜態 ( Static )。Static 在 ES6 就出現了,但在 ES6 的 Class 中只有靜態屬性,沒有靜態方法,而在 TS 中,靜態屬性和方法都有。
預設狀況下,所有在類別中定義的方法和屬性都會被實例繼承,但如果加上 static 關鍵字,轉換成靜態屬性和方法後,則表示該方法或屬性不會被實例繼承,僅存在類別內部,倘若要使用會直接透過類別來調用。
class Something {
static instances = 0;
static foo():number {
return 42;
}
}
//繼承的子類別SomethingMore
class SomethingMore extends Something { }
console.log(SomethingMore.foo()); // 42
//實例化物件s1
const s1 = new Something();
console.log(s1.instances) //Error: Property 'instances' is a static member of type 'Something'
console.log(Something.instances); // 0
上面的程式碼中,由於 instances 屬性為靜態屬性,因此,實例化的物件 s1 並沒有 instances 這個屬性,若要調用,就必須直接透過類別來調用靜態屬性 instances。另外,繼承的子類別 SomethingMore 中可調用父類別的靜態方法foo()。
今天探討了類別內屬性和方法的細節,包括靜態屬性和方法、存取修飾符以及抽象化,明天會繼續探討類別的實踐(implements)。