คลาสใน TypeScript

คลาสใน TypeScript

บทความนี้อธิบายเกี่ยวกับคลาสใน TypeScript

YouTube Video

คลาสใน TypeScript

คลาสใน TypeScript ใช้พื้นฐานจากคลาส ES6 ของ JavaScript และมีคุณสมบัติเพิ่มเติม เช่น การใส่คำอธิบายชนิดข้อมูล (type annotations) และตัวปรับแต่งการเข้าถึง (access modifiers) สิ่งนี้ช่วยให้คุณสามารถใช้แนวคิดของการเขียนโปรแกรมเชิงวัตถุ (object-oriented programming) ในขณะที่ยังคงความปลอดภัยของชนิดข้อมูลที่ชัดเจนและแข็งแกร่งมากขึ้น

ด้านล่างนี้เป็นคำอธิบายการใช้งานพื้นฐานและคุณสมบัติของคลาสใน TypeScript

การกำหนดคลาสพื้นฐาน

 1class Person {
 2    name: string;  // Member variable
 3    age: number;   // Member variable
 4
 5    // Constructor
 6    constructor(name: string, age: number) {
 7        this.name = name;
 8        this.age = age;
 9    }
10
11    // Method
12    greet(): void {
13        console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
14    }
15}
16
17const person = new Person("Alice", 25);
18person.greet();  // Hello, my name is Alice and I am 25 years old.
  • name และ age เป็นคุณลักษณะ (ตัวแปรสมาชิก) ของคลาส
  • constructor เป็นเมธอดที่ถูกเรียกตอนสร้างอินสแตนซ์ของคลาส โดยรับอาร์กิวเมนต์และกำหนดค่าลงในคุณลักษณะ
  • greet เป็นเมธอดของคลาส โดยระบุว่าไม่มีค่าที่คืนกลับมาด้วยการตั้งประเภทเป็น void

ตัวปรับแต่งการเข้าถึง

ใน TypeScript คุณสามารถใช้ตัวปรับแต่งการเข้าถึง (public, private, protected) เพื่อควบคุมการเข้าถึงคุณลักษณะและเมธอดของคลาส

public

โดยค่าเริ่มต้น คุณลักษณะและเมธอดทั้งหมดจะเป็น public หมายความว่าคุณสามารถเข้าถึงได้จากภายนอกคลาส

 1class Animal {
 2    public species: string;
 3
 4    constructor(species: string) {
 5        this.species = species;
 6    }
 7
 8    public makeSound(): void {
 9        console.log(`${this.species} makes a sound.`);
10    }
11}
12
13const animal = new Animal("Dog");
14console.log(animal.species);  // Dog
15animal.makeSound();           // Dog makes a sound.
  • คุณสมบัติ species และเมธอด makeSound ถูกประกาศเป็น public ซึ่งสามารถเข้าถึงได้จากภายนอกคลาส

private

การใช้ตัวปรับแต่ง private จะป้องกันการเข้าถึงคุณลักษณะหรือเมธอดจากภายนอกคลาส

 1class Car {
 2    private brand: string;
 3
 4    constructor(brand: string) {
 5        this.brand = brand;
 6    }
 7
 8    public getBrand(): string {
 9        return this.brand;
10    }
11}
12
13const car = new Car("Toyota");
14// console.log(car.brand);  // Error: 'brand' is private and cannot be accessed.
15console.log(car.getBrand());  // Toyota
  • คุณสมบัติ brand ถูกประกาศเป็น private จึงไม่สามารถเข้าถึงได้จากภายนอกคลาส
  • การห่อหุ้มข้อมูลสามารถทำได้โดยการปกปิดคุณสมบัติด้วยตัวระบุ private

protected

ตัวปรับแต่ง protected จำกัดการเข้าถึงจากภายนอกคลาส แต่อนุญาตให้เข้าถึงได้ในคลาสที่สืบทอด (subclass หรือ derived class)

 1class Vehicle {
 2    protected model: string;
 3
 4    constructor(model: string) {
 5        this.model = model;
 6    }
 7}
 8
 9class Truck extends Vehicle {
10    public getModel(): string {
11        return this.model;
12    }
13}
14
15const truck = new Truck("Ford F-150");
16console.log(truck.getModel());  // Ford F-150
17
18// console.log(truck.model);
19// Error: Property 'model' is protected and only accessible within class 'Vehicle' and its subclasses.
  • คุณสมบัติ model ถูกประกาศเป็น protected จึงไม่สามารถเข้าถึงได้จากภายนอกคลาส แต่สามารถเข้าถึงได้จากคลาสย่อย

ตัวดึงค่าและตัวตั้งค่า (Getters และ Setters)

ใน TypeScript คุณสามารถกำหนด getters และ setters ได้ด้วยการใช้คำสำคัญ get และ set เพื่อดึงค่าและตั้งค่าของคุณลักษณะ

 1class Employee {
 2    private _salary: number;
 3
 4    constructor(salary: number) {
 5        this._salary = salary;
 6    }
 7
 8    // Getter
 9    get salary(): number {
10        return this._salary;
11    }
12
13    // Setter
14    set salary(newSalary: number) {
15        if (newSalary > 0) {
16            this._salary = newSalary;
17        } else {
18            console.log("Salary must be positive.");
19        }
20    }
21}
22
23const employee = new Employee(50000);
24console.log(employee.salary);  // 50000
25employee.salary = 60000;
26console.log(employee.salary);  // 60000
27employee.salary = -100;        // Salary must be positive.
  • ในตัวอย่างนี้ มีการใช้ getter และ setter สำหรับคุณสมบัติ salary เพื่อควบคุมการเข้าถึงและการอัปเดตจากภายนอก setter จะทำการตรวจสอบเพื่อป้องกันค่าติดลบ และแสดงข้อความแจ้งเตือนหากมีการใส่ค่าที่ไม่ถูกต้อง

การสืบทอด

ใน TypeScript คลาสสามารถสืบทอดได้ การใช้คำสำคัญ extends คุณสามารถสืบทอดฟังก์ชันการทำงานจากคลาสต้นแบบ (parent class)

 1class Animal {
 2    constructor(public name: string) {}
 3
 4    public move(): void {
 5        console.log(`${this.name} is moving.`);
 6    }
 7}
 8
 9class Bird extends Animal {
10    public fly(): void {
11        console.log(`${this.name} is flying.`);
12    }
13}
14
15const bird = new Bird("Sparrow");
16bird.move();  // Sparrow is moving.
17bird.fly();   // Sparrow is flying.
  • ในตัวอย่างนี้ คลาส Bird สืบทอดจากคลาส Animal ทำให้สามารถใช้เมธอด move ของ Animal ได้ นอกจากนี้ ยังได้กำหนดเมธอด fly ของตัวเอง โดยเพิ่มความสามารถใหม่ในขณะเดียวกันก็สืบทอดคุณสมบัติจากคลาสแม่

คลาสนามธรรม (Abstract Classes)

คลาสนามธรรม (abstract) ไม่สามารถสร้างอินสแตนซ์ได้โดยตรง และใช้เป็นแม่แบบเพื่อให้ซับคลาสสร้างการแปลงค่าที่ชัดเจน

 1abstract class Shape {
 2    abstract getArea(): number;
 3
 4    public describe(): void {
 5        console.log("This is a shape.");
 6    }
 7}
 8
 9class Circle extends Shape {
10    constructor(private radius: number) {
11        super();
12    }
13
14    public getArea(): number {
15        return Math.PI * this.radius * this.radius;
16    }
17}
18
19const circle = new Circle(5);
20console.log(circle.getArea());  // 78.53981633974483
21circle.describe();  // This is a shape.
  • ในตัวอย่างนี้ Shape ถูกกำหนดให้เป็น abstract class และ getArea เป็น abstract method ที่คลาสย่อยต้องนำไปใช้งาน คลาส Circle สืบทอด abstract class นี้และนำเมธอด getArea ไปใช้งานเพื่อคำนวณพื้นที่ของวงกลม นอกจากนี้ เมธอดที่ไม่เป็น abstract อย่าง describe ยังถูกสืบทอดมาเป็นฟังก์ชันการทำงานทั่วไปและสามารถใช้งานได้ทันที

ความสัมพันธ์กับอินเทอร์เฟซ

คลาสสามารถนำอินเทอร์เฟซไปใช้งานได้ เพื่อให้มั่นใจว่าคลาสนั้นมีคุณลักษณะและเมธอดตามที่กำหนด

 1interface Flyable {
 2    fly(): void;
 3}
 4
 5class Airplane implements Flyable {
 6    public fly(): void {
 7        console.log("The airplane is flying.");
 8    }
 9}
10
11const airplane: Flyable = new Airplane();
12airplane.fly();  // The airplane is flying.
  • ในตัวอย่างนี้ interface ชื่อ Flyable กำหนดข้อกำหนดสำหรับเมธอด fly และคลาส Airplane ได้นำ interface นี้ไปใช้งานโดยให้ความหมายที่ชัดเจนสำหรับเมธอด fly ด้วยเหตุนี้ อ็อบเจกต์ใด ๆ ที่ถือเป็นประเภท Flyable จะต้องมีเมธอด fly อย่างแน่นอน

สมาชิกแบบ Static

เมื่อคุณกำหนด สมาชิกแบบ static ในคลาส เมธอดและคุณสมบัติเหล่านั้นจะผูกกับคลาสเอง สมาชิกแบบ static สามารถถูกเรียกใช้งานได้โดยไม่ต้องสร้างอินสแตนซ์ของคลาส

 1class MathUtils {
 2    static PI: number = 3.14;
 3
 4    static add(a: number, b: number): number {
 5        return a + b;
 6    }
 7}
 8
 9console.log(MathUtils.add(10, 20)); // 30
10console.log(MathUtils.PI); // 3.14
  • คุณสามารถกำหนดเมธอดแบบ static ได้โดยใช้คีย์เวิร์ด static
  • ในตัวอย่างนี้ คลาส MathUtils ได้กำหนดเมธอดแบบ static ชื่อ add และคุณสมบัติแบบ static ชื่อ PI
  • สมาชิกแบบ static ไม่ได้เป็นของอินสแตนซ์ของคลาส แต่สามารถเรียกใช้งานได้โดยตรงจากคลาสเอง

สรุป

คลาส TypeScript เพิ่มคุณสมบัติต่าง ๆ เช่น ความปลอดภัยของประเภท ตัวปรับแต่งการเข้าถึง และคลาสแบบนามธรรม ให้กับฟังก์ชันคลาสของ JavaScript สิ่งนี้ช่วยให้การเขียนโปรแกรมเชิงวัตถุมีประสิทธิภาพและปลอดภัยมากขึ้น

คุณสามารถติดตามบทความข้างต้นโดยใช้ Visual Studio Code บนช่อง YouTube ของเรา กรุณาตรวจสอบช่อง YouTube ด้วย

YouTube Video