คลาสใน 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 ด้วย