TypeScript - Classes

TypeScript - Classes

本篇的主旨:

  • Class 的運用
  • Class + Interface 的運用

    Class 的基本應用

1
2
3
4
5
6
7
8
class Post {
page(): void {
console.log('第四篇了')
}
}

let post = new Post();
post.page(); // 第四篇了

extends

若是要建立另一個 Class,但同時包含上面的 Class 的內容,可以使用 extends 來做擴展

1
2
3
class News extends Post {}
let news = new News();
news.page(); // 第四篇了

也可以覆蓋原本定義的方法:

1
2
3
4
5
6
7
class News extends Post {
page(): void {
console.log('這是 news')
}
}
let news = new News();
news.page(); // 這是 news

Modifiers

  • Public:任何類別以及繼承的子類別都可以調用。
  • Private:只有當前類別內可以調用。

如以下範例,若是調用 .page() 的話,則會出現錯誤。

1
2
3
4
5
6
7
8
class Post {
private page(): void {
console.log('第四篇了')
}
}

let post = new Post();
post.page(); // Property 'page' is private and only accessible within class 'Post'

加上 private 因為只能在當前類別中調用,所以應該這樣使用:
用 displayPage 調用 page,外部再呼叫 displayPage 函式

1
2
3
4
5
6
7
8
9
10
11
class Post {
private page(): void {
console.log('第四篇了')
}
displayPage(): void {
this.page()
}
}

let post = new Post();
post.displayPage(); // 第四篇了

  • protected:除了當前類別,繼承的子類別也可以調用
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class Post {
    protected page(): void {
    console.log('第四篇了')
    }
    }
    class News extends Post {
    disaplayPage(): void {
    this.page()
    }
    }
    let news = new News();
    news.disaplayPage(); // 第四篇了

透過設定 Modifiers 可以確保某些函式無法隨意被調用,在 TS 中是會出現錯誤,但也要注意在編譯後是不會有限制的,所以仍是可以執行的。

constructor

使用 constructor 可以在 Class 中定義一個構造函式。

1
2
3
4
5
class Post {
constructor(public page: number) {}
}
let post = new Post(2);
console.log(post.page) // 2

super

1
2
3
4
5
6
7
8
9
10
11
12
13
class Post {
constructor(public page: number) {}
}
class News extends Post {
constructor(public type: string, page: number) {
super(page) // 繼承 Post 的 constructor 參數
}
displayPage(): void {
console.log(this.type + this.page)
}
}
let news = new News('news', 4);
news.displayPage(); // news4

Classes & Interfaces

在前一篇 Interfaces 提到,它是用來定義值的型別,可以說是用來描述他的 Shape(形),而實際行為則需要透過 Classes 來制定。

如以下的舉例:
新聞 (News) 與部落格 (Blog) 都具有文章,而文章(Article)都需要包含了名稱以及第幾頁,因此我們用 interface 來定義 Article 需要包含的內容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
interface Article {
name: string;
page: number;
}

class News implements Article {
name: string;
page: number;
constructor(name: string, page: number) {
this.name = name;
this.page = page
}
}

class Blog implements Article {
name: string;
page: number;
constructor(name: string, page: number) {
this.name = name;
this.page = page
}
}

let news = new News('新聞', 1);
let blog = new Blog('部落格', 4);

可以發現兩個 class 中的內容是重複的,因此也可以使用一個 Class 來做擴展,以下範例在 interface 還多增加一個 read,但 read 是的宣告是用在 News 這個 class 中的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
interface Article {
name: string;
page: number;
read: boolean;
}

class Post {
name: string;
page: number;
constructor(name: string, page: number) {
this.name = name;
this.page = page
}
}

class News extends Post implements Article {
constructor(public read: boolean, name: string, page: number) {
super(name, page)
}
display() {
console.log(this.name + this.page + '必讀:' + this.read)
}
}

let news = new News(false, '新聞', 1);
news.display(); //

implements 也可以用兩個 interface,這邊把剛剛的 read 獨立出來,
只在 News 這個 class 去 implements。則在 News 就需要有 read,但 Blog 就可以不用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
interface Article {
name: string;
page: number;
}

interface ArticleRead {
read: boolean;
}

class Post {
name: string;
page: number;
constructor(name: string, page: number) {
this.name = name;
this.page = page
}
}

class News extends Post implements Article, ArticleRead {
constructor(public read: boolean, name: string, page: number) {
super(name, page)
}
display() {
console.log(this.name + this.page + '必讀:' + this.read)
}
}

class Blog extends Post implements Article {
display() {
console.log(this.name + this.page)
}
}

let news = new News(false, '新聞', 1);
news.display();

let blog = new Blog('部落格', 4);
blog.display();

小補充

interface 也可以繼承 interface,這樣的話,news 必須與有 read

1
2
3
4
5
6
7
8
9
10
11
12
interface ArticleRead {
read: boolean;
}
interface Article extends ArticleRead {
name: string;
page: number;
}
let news: Article = {
name: '文章',
page: 5,
read: false,
}

透過 Class 可以建構可重複使用的組件,而加上 Interfaces 可以將共通的部分提取出來,讓共通處可以確保參數及其型別的定義都為一致。

參考資料:
Class - TypeScript
Udemy - Typescript: The Complete Developer’s Guide 2020
類別與介面 - TypeScript 新手指南

評論

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×