ใน TypeScript Interface และ Abstract Class เป็นเครื่องมือหลักในการสร้าง สัญญา (Contract) และพิมพ์เขียวของโค้ดเชิงวัตถุ (OOP) เพื่อให้เกิดความสอดคล้องและยืดหยุ่นในการพัฒนา
1. การใช้งาน Interface
แตกต่างจาก Dart ที่ Class ทุกตัวเป็น Interface โดยปริยาย ใน TypeScript เราใช้คีย์เวิร์ด interface ในการกำหนดโครงสร้างของ Object, Properties และ Methods อย่างชัดเจน
Interface ใช้เพื่อกำหนด สัญญา ว่า Class หรือ Object ใด ๆ ที่นำไปใช้จะต้องมีคุณสมบัติตามที่กำหนด
A. การกำหนด Interface
// การกำหนด Interface
interface Shape {
// ต้องมี property นี้
width: number;
height: number;
// ต้องมี method นี้ โดยมีการกำหนด parameter และ return type
area(): number;
perimeter(): number;
}
B. การใช้งาน implements
เราใช้คีย์เวิร์ด implements เพื่อให้ Class รับสัญญาจาก Interface มาใช้ Class ที่ implements Interface จะต้องทำการกำหนดรายละเอียดของ Properties และ Methods ทั้งหมดตามที่ Interface กำหนดไว้
// Class Rectangle implements สัญญาจาก Shape
class Rectangle implements Shape {
// ต้องประกาศ Properties ทั้งหมดตามสัญญา
width: number;
height: number;
constructor(width: number, height: number) {
this.width = width;
this.height = height;
}
// ต้องกำหนด Body ให้กับ Method area()
area(): number {
return this.width * this.height;
}
// ต้องกำหนด Body ให้กับ Method perimeter()
perimeter(): number {
return (this.width * 2) + (this.height * 2);
}
}
C. Multiple Interface Implementation
TypeScript อนุญาตให้ Class หนึ่งสามารถ implements Interface ได้หลายตัวพร้อมกัน ซึ่งช่วยให้ Object นั้นสามารถมีคุณสมบัติและพฤติกรรมตามสัญญาได้หลายแบบ
interface HasVolume {
volume(): number;
}
// Cylinder implements ทั้ง Shape และ HasVolume
class Cylinder implements Shape, HasVolume {
// ... ต้องประกาศ property และ method ทั้งหมดของ Shape และ HasVolume
// ... (โค้ดส่วนอื่น ๆ)
area(): number { /* ... */ return 0; }
perimeter(): number { /* ... */ return 0; }
volume(): number { /* ... */ return 0; }
}
2. การใช้งาน Abstract Class
Abstract Class คือ Class ที่ไม่สามารถนำไปสร้าง Object ได้โดยตรง (ไม่สามารถใช้ new ได้) แต่มีจุดประสงค์หลักเพื่อเป็น Base Class ที่ Class ลูกอื่น ๆ จะต้องนำไปสืบทอด (extends) หรือ implements ต่อไป
A. การกำหนด Abstract Class
ใช้คีย์เวิร์ด abstract นำหน้าชื่อ Class
// Abstract Class รูปร่าง
abstract class Form {
// 1. Normal Property (มีค่าได้)
protected color: string = 'gray';
// 2. Normal Method (มี Body ได้)
public getColor(): string {
return this.color;
}
// 3. Abstract Method (ต้องไม่มี Body และมี abstract keyword)
abstract area(): number; // ต้องถูก implements/override ใน Class ลูก
}
B. Abstract Method
Abstract Method คือ Method ที่ถูกประกาศไว้ใน Abstract Class โดย ไม่มีการกำหนด Body ({}) ซึ่งบังคับให้ Class ลูกทั้งหมดที่สืบทอด (extends) จะต้องทำการกำหนด Body ให้กับ Method นั้น ๆ
// Class ลูกต้อง extends
class Triangle extends Form {
base: number;
height: number;
constructor(base: number, height: number) {
super();
this.base = base;
this.height = height;
}
// ต้อง Override และกำหนด Body ให้กับ abstract method 'area()'
override area(): number {
return 0.5 * this.base * this.height;
}
}
// const f = new Form(); // Error: Cannot create an instance of an abstract class.
const t = new Triangle(10, 5);
console.log(t.area()); // 25
3. Interface vs. Abstract Class
| คุณสมบัติ | Interface | Abstract Class |
| คีย์เวิร์ด |
interface |
abstract class |
| การสร้าง Object | ไม่ได้ | ไม่ได้ |
| การรับสัญญา |
ใช้ implements (รับได้หลายตัว) |
ใช้ extends (รับได้ตัวเดียว) หรือ implements |
| มี Logic/Body | ไม่ได้ (กำหนดเพียงโครงสร้าง) | ได้ (มี Normal Method ที่มี Body ได้) |
| ใช้ Access Modifier |
ไม่ได้ (ทุกอย่างเป็น public โดยปริยาย) |
ได้ (public, private, protected) |
| ใช้ Constructor | ไม่ได้ | ได้ |
Interface มักถูกใช้เพื่อกำหนด Contracts ที่หลากหลายสำหรับ Object หรือ Class ที่ไม่จำเป็นต้องมีความเกี่ยวข้องกันโดยตรง (Polymorphism)
Abstract Class มักถูกใช้เป็น Base Class ที่มี Logic หรือ Properties ร่วมกันบางส่วน และต้องการบังคับให้ Class ลูกมีพฤติกรรมบางอย่างที่จำเป็น (Template Method Pattern)