メインコンテンツへ移動

เนื้อหาภาษาไทย / タイ語のコンテンツ

システムガイド 内容確認済み

Interfaces: การกำหนดสัญญา

บทความนี้อธิบายถึง **Interface** ในการเขียนโปรแกรมเชิงวัตถุ ซึ่งเป็นเหมือน "สัญญา" ที่ Class ต่างๆ ต้อง Implement โดย Interface กำหนดชุดของ Method ที่ Class ต้อ...

Interfaces: การกำหนดสัญญา

ในโลกของการเขียนโปรแกรมเชิงวัตถุ (OOP) นอกจากการสืบทอด (Inheritance) แล้ว ยังมีอีกแนวคิดที่สำคัญไม่แพ้กัน นั่นคือ Interface ซึ่งเปรียบเสมือน "สัญญา" ที่ Class ต่างๆ ต้องปฏิบัติตาม หาก Class ใด "รับปาก" ที่จะ Implement Interface นั้นแล้ว จะต้อง Implement ทุก Method ที่ Interface กำหนดไว้

ความหมายของ Interfaces

Interfaces คือโครงสร้างที่กำหนดชุดของ Methods โดยไม่มีการ Implement ใดๆ ทั้งสิ้น กล่าวคือ Interfaces จะบอกเพียงว่า "Class นี้ต้องมี Method อะไรบ้าง" แต่ไม่ได้บอกว่า "Method เหล่านั้นต้องทำงานอย่างไร"

ลองนึกภาพว่าคุณกำลังสร้างระบบแจ้งเตือน (Notification System) คุณอาจต้องการให้ระบบนี้รองรับการแจ้งเตือนผ่านหลายช่องทาง เช่น อีเมล, SMS, หรือ Push Notification แต่ละช่องทางก็อาจมีวิธีการส่งที่แตกต่างกัน แต่สิ่งที่คุณต้องการคือ "ทุกช่องทางต้องมี Method สำหรับส่งข้อความ"

Interface จะช่วยให้คุณกำหนด "สัญญา" นี้ได้ โดยบอกว่า "Class ที่ใช้ส่ง Notification ต้องมี Method ชื่อ `send()`" ส่วนการ Implement ว่า `send()` จะส่งอีเมล, SMS, หรือ Push Notification นั้น เป็นหน้าที่ของแต่ละ Class ที่ Implement Interface

การสร้าง Interfaces

ใน PHP เราสร้าง Interface โดยใช้ Keyword `interface` ตามด้วยชื่อ Interface และภายใน Block `{}` จะเป็นการกำหนด Methods ที่ Interface นั้นต้องการ

<?php

interface Logger {
    public function log(string $message);
}

?>

จากตัวอย่างด้านบน เราได้สร้าง Interface ชื่อ `Logger` ซึ่งกำหนดว่า Class ที่ Implement `Logger` จะต้องมี Method ชื่อ `log()` ที่รับ Parameter เป็น String และไม่มีการ Return ค่า

ข้อสังเกต:

  • Methods ใน Interface จะต้องเป็น `public` เสมอ เพราะจุดประสงค์ของ Interface คือการกำหนดสิ่งที่ Class อื่นๆ สามารถเรียกใช้ได้
  • Methods ใน Interface ไม่มี Body (ไม่มี Code ภายใน `{}`) เพราะ Interface เป็นเพียงการกำหนดโครงสร้าง ไม่ได้กำหนดการทำงาน

การ Implement Interfaces

เมื่อเรามี Interface แล้ว เราสามารถให้ Class ต่างๆ "Implement" Interface นั้นได้ โดยใช้ Keyword `implements` ตามด้วยชื่อ Interface

<?php

interface Logger {
    public function log(string $message);
}

class FileLogger implements Logger {
    private $filePath;

    public function __construct(string $filePath) {
        $this->filePath = $filePath;
    }

    public function log(string $message) {
        file_put_contents($this->filePath, $message . PHP_EOL, FILE_APPEND);
    }
}

?>

จากตัวอย่างด้านบน เราได้สร้าง Class ชื่อ `FileLogger` ซึ่ง Implement Interface `Logger` นั่นหมายความว่า `FileLogger` จะต้องมี Method ชื่อ `log()` ที่รับ Parameter เป็น String และไม่มีการ Return ค่า

ภายใน Class `FileLogger` เราได้ Implement Method `log()` โดยการเขียนข้อความลงในไฟล์ที่กำหนดไว้ใน Constructor

ข้อสำคัญ: หาก Class ใด Implement Interface แล้ว แต่ไม่ได้ Implement Methods ทั้งหมดที่ Interface กำหนดไว้ PHP จะ Throw Error ทันที

ตัวอย่าง:

<?php

interface Logger {
    public function log(string $message);
    public function error(string $message);
}

class FileLogger implements Logger {
    private $filePath;

    public function __construct(string $filePath) {
        $this->filePath = $filePath;
    }

    public function log(string $message) {
        file_put_contents($this->filePath, $message . PHP_EOL, FILE_APPEND);
    }
}

// Warning: Class FileLogger contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Logger::error)
?>

ในตัวอย่างนี้ Interface `Logger` กำหนดให้มี Method `log()` และ `error()` แต่ Class `FileLogger` Implement เพียง `log()` เท่านั้น ทำให้ PHP Throw Warning ว่า Class `FileLogger` ยังมี Abstract Method ที่ต้อง Implement

เราสามารถแก้ไขได้โดยการ Implement Method `error()` ใน Class `FileLogger` ดังนี้

<?php

interface Logger {
    public function log(string $message);
    public function error(string $message);
}

class FileLogger implements Logger {
    private $filePath;

    public function __construct(string $filePath) {
        $this->filePath = $filePath;
    }

    public function log(string $message) {
        file_put_contents($this->filePath, $message . PHP_EOL, FILE_APPEND);
    }

    public function error(string $message) {
        error_log($message, 3, $this->filePath); // Log error using error_log
    }
}

?>

นอกจากนี้ Class หนึ่งสามารถ Implement หลาย Interfaces ได้ โดยใช้ Comma (`,`) คั่นระหว่างชื่อ Interface

<?php

interface Loggable {
    public function log(string $message);
}

interface Auditable {
    public function audit(string $action);
}

class User implements Loggable, Auditable {
    private $username;

    public function __construct(string $username) {
        $this->username = $username;
    }

    public function log(string $message) {
        // Implement logging logic here
        echo "Logging: " . $message . PHP_EOL;
    }

    public function audit(string $action) {
        // Implement auditing logic here
        echo "Auditing: " . $action . " for user " . $this->username . PHP_EOL;
    }
}

$user = new User("john_doe");
$user->log("User logged in");
$user->audit("Created account");

?>

จากตัวอย่างนี้ Class `User` Implement ทั้ง Interface `Loggable` และ `Auditable` ทำให้ Class `User` ต้อง Implement Method `log()` จาก `Loggable` และ Method `audit()` จาก `Auditable`

สรุป: Interfaces เป็นเครื่องมือที่สำคัญในการออกแบบ OOP ที่ช่วยให้เรากำหนด "สัญญา" ที่ Class ต่างๆ ต้องปฏิบัติตาม ทำให้ Code ของเรามีความยืดหยุ่น, บำรุงรักษาง่าย, และสามารถขยายความสามารถได้ง่ายขึ้น ในบทถัดไป เราจะมาดูเรื่อง Polymorphism ซึ่งเป็นอีกหนึ่งแนวคิดที่สำคัญที่ทำงานร่วมกับ Interface ได้อย่างมีประสิทธิภาพ

Office.in.th Custom Service

この構成をもとにシステムを開発・カスタマイズしたいですか?

Office.in.th は、エンタープライズ Web アプリケーション、API 連携、官民の業務管理システムの設計・開発を承り、長期的なサポートも提供します。

ソフトウェア開発サービスを見る