TypeScript 基礎:物件導向與類別基礎

什麼是類別?
類別是一個基礎的物件導向設計(Object-Oriented Programming, OOP),是一種以物件為中心的編程範式,強調模擬現實世界的實體與行為。類別將資料(屬性)和行為(方法)整合在一起,方便定義和操作不同的物件實例。
類別(Class)
現在 ES6 標準化後,開發者可以使用更直觀的 class 語法來實現物件導向設計,簡化類別定義和繼承,提升程式結構性。
class Person {
name: string
age: number
constructor(name: string, age: number) {
this.name = name
this.age = age
}
speak() {
console.log(`嗨!我的名字是${this.name},我今年${this.age}歲。`)
}
}
const person = new Person('阿毛', 18)
person.speak() // 嗨!我的名字是阿毛,我今年18歲。繼承(Inheritance)
類別的繼承,允許子類別(subclass)繼承父類別(superclass)的屬性和方法。子類別可以重寫父類別的方法,或是擴展新功能。
class Employee extends Person {
position: string
constructor(name: string, age: number, position: string) {
super(name, age) // 呼叫父類別的建構子
this.position = position
}
introduce() {
console.log(`我是${this.name},是${this.position}。`)
}
}
const employee = new Employee('阿毛', 18, '前端工程師')
employee.speak() // 嗨!我的名字是阿毛,我今年18歲。
employee.introduce() // 我是阿毛,是前端工程師。覆寫方法(Override method)
子類別中重新定義從父類繼承來的方法,取代父類的實現。雖然不寫 override 也不會有問題,但有寫的話,會幫你校正拼字錯誤。
class Ironman extends Person {
override speak() {
console.log(`${this.name}正在努力撰寫鐵人賽文章...`)
}
}
const ironman = new Ironman('阿毛', 18)
ironman.speak() // 阿毛正在努力撰寫鐵人賽文章...簡寫形式
TypeScript 提供了一個建構子參數的簡寫形式來直接定義和初始化類別的屬性。只需在建構子的參數前加上下面的修飾詞,便可簡化屬性宣告和賦值的過程。
class Person {
// 通過修飾詞簡化原本的寫法
constructor(public name: string, public age: number) {}
speak() {
console.log(`嗨!我的名字是${this.name},我今年${this.age}歲。`)
}
}
const person = new Person('阿毛', 18)
person.speak() // 嗨!我的名字是阿毛,我今年18歲。屬性修飾詞
公開修飾詞(public)
public 修飾詞是 TypeScript 的預設設定,表示屬性或方法可以在任何地方被訪問,不寫的話預設就是 public。
class Person {
constructor(public name: string, public age: number) {}
public speak() {
console.log(`嗨!我的名字是${this.name},我今年${this.age}歲。`)
}
}受保護修飾詞(protected)
protected 修飾詞表示屬性或方法只能在類別內部及其子類別中被訪問,而不能在類別外部被訪問。
class Person {
constructor(protected name: string, protected age: number) {}
protected getInfo() {
return `嗨!我的名字是${this.name},我今年${this.age}歲。`
}
speak() {
console.log(this.getInfo())
}
}
class Ironman extends Person {
write() {
// this.name 一樣可以正常使用
console.log(`${this.name}正在努力撰寫鐵人賽文章...`)
}
}
const ironman = new Ironman('阿毛', 18)
ironman.speak() // 嗨!我的名字是阿毛,我今年18歲。
ironman.write() // 阿毛正在努力撰寫鐵人賽文章...
// Error: 下面這三個都是受保護屬性,只可從類別 'Person' 及其子類別中存取。
// console.log(ironman.name);
// console.log(ironman.age);
// ironman.getInfo();私有修飾詞(private)
private 修飾詞表示屬性或方法只能在類別內部訪問,無法在子類別或外部使用。
class Person {
constructor(
protected name: string,
protected age: number,
private idCard: string,
) {}
}
class Ironman extends Person {
write() {
// this.name 一樣可以正常使用
console.log(`${this.name}正在努力撰寫鐵人賽文章...`)
}
getSuperclassPrivate() {
// Error: 'idCard' 是私用屬性,只可從類別 'Person' 中存取。
// return this.idCard;
}
}
const ironman = new Ironman('阿毛', 18, 'A123456789')
ironman.write() // 阿毛正在努力撰寫鐵人賽文章...。
// Error: 'idCard' 是私用屬性,只可從類別 'Person' 中存取。
// console.log(ironman.idCard);只讀修飾詞(readonly)
readonly 修飾詞使屬性只能在初始化時賦值,之後不可更改。這提供了一種保護機制,防止屬性被意外修改。
class Ironman {
constructor(public readonly title: string) {}
showTitle() {
console.log(`鐵人賽文章標題:「${this.title}」`)
}
}
const ironman = new Ironman('TypeScript 完全指南:從語法基礎到高級功能的系統學習')
ironman.showTitle() // 鐵人賽文章標題:「TypeScript 完全指南:從語法基礎到高級功能的系統學習」
// Error: 因為 'title' 為唯讀屬性,所以無法指派至 'title'。
// ironman.title = '我想變更標題';參考文獻
Related Posts
TypeScript 後記
終於完成連續三十天的鐵人賽文章撰寫!距離我第一次參加鐵人賽已經三年之久了。這次參加主要是因為朋友邀請一起參賽,同時我自己也想藉此機會深入了解 TypeScript 5 的新功能,強迫自己透過寫作來吸收知識。
TypeScript 實戰:製作 npm Package
在開發專案時,經常會遇到跨專案共用邏輯或工具的情況,例如常用的 logger 或驗證工具。如果每次都從一個專案複製貼上到另一個專案,難免會出現版本不同步或維護困難的問題。為了解決這類問題,我們可以將這些共用邏輯獨立成為 npm 套件,以便在多個專案中重複使用。
TypeScript 實戰:前端表單與串接 API
在現代前端開發中,與後端進行資料交換是常見的需求。透過 HTTP 請求,我們可以將資料送出並取得結果。這篇文章將介紹如何使用 TypeScript 實作前端表單與串接 API,並展示如何將這些功能結合到 React 應用中。同時,文章還會介紹如何解決跨域問題(CORS),以便讓前後端能順利溝通。
Johnson Mao
A passionate software engineer and blogger sharing thoughts on technology, AI, and development.