更新於 2024/06/12閱讀時間約 15 分鐘

Typescript入門-Day8:物件導向

類別(Class)

在 TypeScript 中,類別(class)是面向對象編程的核心概念。類別用於創建對象,並且可以包含屬性和方法。

建構子(Constructor)

建構子(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)修飾符用於指定類別成員的訪問權限。被標記為 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)修飾符用於指定類別成員的訪問權限。被標記為 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)修飾符用於指定類別成員的訪問權限。被標記為 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

繼承(Inheritance)

繼承是面向對象編程的一個基本概念,通過繼承,一個類別可以從另一個類別獲取屬性和方法。

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

多型(Polymorphism)

多型允許不同類別的對象以相同的方式做出反應,儘管它們的具體實現不同。

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

封裝(Encapsulation)

封裝是將數據和操作數據的方法綁定在一起,並隱藏內部實現細節的一種技術。

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)

介面定義了一個類別必須遵循的結構。它只定義屬性和方法的類型,而不提供具體的實現。

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)

抽象類別是一種不能被實例化的類別,通常用於定義子類別必須實現的方法。

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...

靜態類別(Static Class)

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

列舉(Enumerations)

列舉是一種數據類型,用於定義一組命名常數。

enum Color {
Red,
Green,
Blue
}

let color: Color = Color.Green;
console.log(color); // 1

console.log(Color[2]); // Blue

委派(Delegates)

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 表達式

Lambda 表達式在 TypeScript 中是通過箭頭函數實現的。

let sum = (a: number, b: number): number => a + b;

console.log(sum(5, 3)); // 8

泛型(Generics)

泛型允許你創建可重用的組件,這些組件可以適用於多種數據類型。

function identity<T>(arg: T): T {
return arg;
}

console.log(identity<number>(5)); // 5
console.log(identity<string>("Hello")); // Hello

反射(Reflection)

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

分享至
成為作者繼續創作的動力吧!
© 2024 vocus All rights reserved.