在 TypeScript 中,類別(class)是面向對象編程的核心概念。類別用於創建對象,並且可以包含屬性和方法。
建構子(constructor)是類別的一種特殊方法,用於在創建類別的實例時初始化對象。
class Person {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
greet() {
console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
}
}
let person = new Person("Alice", 30);
person.greet(); // Hello, my name is Alice and I am 30 years old.
公開(public)修飾符用於指定類別成員的訪問權限。被標記為 public
的成員可以從類別的內部和外部訪問。
class Animal {
public name: string;
constructor(name: string) {
this.name = name;
}
public move(distance: number): void {
console.log(`${this.name} moved ${distance} meters.`);
}
}
let dog = new Animal("Dog");
dog.move(10); // Dog moved 10 meters.
私有(private)修飾符用於指定類別成員的訪問權限。被標記為 private
的成員只能在類別的內部訪問。
class Car {
private speed: number;
constructor(speed: number) {
this.speed = speed;
}
public accelerate(): void {
this.speed += 10;
console.log(`Speed is now ${this.speed}`);
}
}
let car = new Car(50);
car.accelerate(); // Speed is now 60
// console.log(car.speed); // Error: Property 'speed' is private and only accessible within class 'Car'.
受保護(protected)修飾符用於指定類別成員的訪問權限。被標記為 protected
的成員只能在類別的內部和其子類別中訪問。
class Employee {
protected id: number;
constructor(id: number) {
this.id = id;
}
}
class Manager extends Employee {
private department: string;
constructor(id: number, department: string) {
super(id);
this.department = department;
}
public getDepartment(): string {
return this.department;
}
public getId(): number {
return this.id;
}
}
let manager = new Manager(1, "HR");
console.log(manager.getDepartment()); // HR
console.log(manager.getId()); // 1
繼承是面向對象編程的一個基本概念,通過繼承,一個類別可以從另一個類別獲取屬性和方法。
class Person {
name: string;
constructor(name: string) {
this.name = name;
}
greet() {
console.log(`Hello, my name is ${this.name}`);
}
}
class Employee extends Person {
id: number;
constructor(name: string, id: number) {
super(name);
this.id = id;
}
showId() {
console.log(`My ID is ${this.id}`);
}
}
let employee = new Employee("Alice", 123);
employee.greet(); // Hello, my name is Alice
employee.showId(); // My ID is 123
多型允許不同類別的對象以相同的方式做出反應,儘管它們的具體實現不同。
class Shape {
area(): number {
return 0;
}
}
class Circle extends Shape {
radius: number;
constructor(radius: number) {
super();
this.radius = radius;
}
area(): number {
return Math.PI * this.radius * this.radius;
}
}
class Rectangle extends Shape {
width: number;
height: number;
constructor(width: number, height: number) {
super();
this.width = width;
this.height = height;
}
area(): number {
return this.width * this.height;
}
}
let shapes: Shape[] = [new Circle(10), new Rectangle(5, 10)];
shapes.forEach(shape => {
console.log(shape.area());
});
// Output:
// 314.1592653589793
// 50
封裝是將數據和操作數據的方法綁定在一起,並隱藏內部實現細節的一種技術。
class Account {
private balance: number;
constructor(initialBalance: number) {
this.balance = initialBalance;
}
public deposit(amount: number): void {
this.balance += amount;
console.log(`Deposited ${amount}, new balance is ${this.balance}`);
}
public withdraw(amount: number): void {
if (this.balance >= amount) {
this.balance -= amount;
console.log(`Withdrew ${amount}, new balance is ${this.balance}`);
} else {
console.log("Insufficient funds");
}
}
public getBalance(): number {
return this.balance;
}
}
let account = new Account(1000);
account.deposit(500); // Deposited 500, new balance is 1500
account.withdraw(200); // Withdrew 200, new balance is 1300
console.log(account.getBalance()); // 1300
介面定義了一個類別必須遵循的結構。它只定義屬性和方法的類型,而不提供具體的實現。
interface Drawable {
draw(): void;
}
class Circle implements Drawable {
draw(): void {
console.log("Drawing a circle");
}
}
class Square implements Drawable {
draw(): void {
console.log("Drawing a square");
}
}
let shapes: Drawable[] = [new Circle(), new Square()];
shapes.forEach(shape => shape.draw());
// Output:
// Drawing a circle
// Drawing a square
抽象類別是一種不能被實例化的類別,通常用於定義子類別必須實現的方法。
abstract class Animal {
abstract makeSound(): void;
move(): void {
console.log("Moving...");
}
}
class Dog extends Animal {
makeSound(): void {
console.log("Barking");
}
}
let dog = new Dog();
dog.makeSound(); // Barking
dog.move(); // Moving...
TypeScript 沒有專門的靜態類別,但可以使用靜態成員來實現類似的功能。
class MathUtil {
static PI: number = 3.14159;
static areaOfCircle(radius: number): number {
return MathUtil.PI * radius * radius;
}
}
console.log(MathUtil.areaOfCircle(10)); // 314.159
列舉是一種數據類型,用於定義一組命名常數。
enum Color {
Red,
Green,
Blue
}
let color: Color = Color.Green;
console.log(color); // 1
console.log(Color[2]); // Blue
TypeScript 沒有內建的委派,但可以通過函數或接口來實現類似的功能。
interface MathOperation {
(a: number, b: number): number;
}
let add: MathOperation = (a, b) => a + b;
let subtract: MathOperation = (a, b) => a - b;
console.log(add(5, 3)); // 8
console.log(subtract(5, 3)); // 2
Lambda 表達式在 TypeScript 中是通過箭頭函數實現的。
let sum = (a: number, b: number): number => a + b;
console.log(sum(5, 3)); // 8
泛型允許你創建可重用的組件,這些組件可以適用於多種數據類型。
function identity<T>(arg: T): T {
return arg;
}
console.log(identity<number>(5)); // 5
console.log(identity<string>("Hello")); // Hello
TypeScript 中沒有原生的反射機制,但可以通過一些第三方庫來實現。
// 使用 reflect-metadata 庫
import "reflect-metadata";
class Plane {
@Reflect.metadata("role", "transport")
fly() {
console.log("Flying...");
}
}
let plane = new Plane();
let metadataValue = Reflect.getMetadata("role", plane, "fly");
console.log(metadataValue); // transport