跳到主要内容

เนื้อหาภาษาไทย / 泰语内容

系统指南 内容已审核

Abstract Classes: Class ที่ยังไม่สมบูรณ์

Abstract Classes: Class ที่ยังไม่สมบูรณ์

ในบทที่แล้ว เราได้เรียนรู้เรื่อง Traits ซึ่งเป็นวิธีที่ยอดเยี่ยมในการนำโค้ดกลับมาใช้ใหม่ในหลายๆ Class โดยไม่ต้องพึ่ง Inheritance แต่ในบางสถานการณ์ เราอาจต้องการกำหนดโครงสร้างพื้นฐานบางอย่างที่ Class ลูกจะต้องปฏิบัติตาม แต่ไม่อยากให้ Class แม่สามารถนำไปใช้งานได้โดยตรง นี่คือจุดที่ Abstract Classes เข้ามามีบทบาท

ความหมายของ Abstract Classes

Abstract Class (คลาส Abstract) คือ Class ที่ไม่สามารถสร้าง Object ได้โดยตรง มันเป็นเหมือนพิมพ์เขียว (Blueprint) หรือแม่แบบที่กำหนดโครงสร้างและพฤติกรรมที่ Class ลูกจะต้อง Implement (ทำให้เป็นจริง) คล้ายกับ Interface แต่มีความแตกต่างกันตรงที่ Abstract Class สามารถมี Methods ที่มี Implementation แล้วได้ (Concrete Methods) ในขณะที่ Interface มีได้เฉพาะ Method Declaration (Method ที่ไม่มี Body)

พูดง่ายๆ คือ Abstract Class เป็น Class ที่ "ยังไม่สมบูรณ์" มันมีส่วนที่ยังขาดหายไป (Abstract Methods) ซึ่ง Class ลูกจะต้องเข้ามาเติมเต็มให้สมบูรณ์

การสร้าง Abstract Classes

ในการสร้าง Abstract Class ใน PHP เราใช้ keyword abstract นำหน้า keyword class ดังนี้:

abstract class Animal {
  // Properties
  protected $name;

  // Constructor
  public function __construct($name) {
    $this->name = $name;
  }

  // Concrete Method (Method ที่มี Implementation)
  public function getName() {
    return $this->name;
  }

  // Abstract Method (Method ที่ไม่มี Implementation)
  abstract public function makeSound();
}

จากตัวอย่างข้างต้น:

  • abstract class Animal: ประกาศ Class Animal ให้เป็น Abstract Class
  • protected $name;: ประกาศ Property ชื่อ $name ซึ่ง Class ลูกสามารถเข้าถึงได้
  • public function __construct($name): Constructor สำหรับกำหนดชื่อของสัตว์
  • public function getName(): Method ที่ return ชื่อของสัตว์ (Concrete Method)
  • abstract public function makeSound();: Method ที่ไม่มี Implementation (Abstract Method) Class ลูกจะต้อง Implement Method นี้

ข้อสังเกต: Abstract Class สามารถมีทั้ง Concrete Methods และ Abstract Methods ได้

การ Implement Abstract Methods

เมื่อเราสร้าง Class ลูกที่สืบทอดมาจาก Abstract Class เราจะต้อง Implement Abstract Methods ทั้งหมดที่อยู่ใน Class แม่ มิฉะนั้น Class ลูกก็จะกลายเป็น Abstract Class ไปด้วย

ตัวอย่าง:

class Dog extends Animal {
  public function makeSound() {
    return "Woof!";
  }
}

class Cat extends Animal {
  public function makeSound() {
    return "Meow!";
  }
}

// ลองสร้าง Object
$dog = new Dog("Buddy");
echo $dog->getName() . " says: " . $dog->makeSound() . "<br>"; // Buddy says: Woof!

$cat = new Cat("Whiskers");
echo $cat->getName() . " says: " . $cat->makeSound() . "<br>"; // Whiskers says: Meow!

จากตัวอย่าง:

  • class Dog extends Animal และ class Cat extends Animal: ประกาศ Class Dog และ Cat ให้สืบทอดมาจาก Abstract Class Animal
  • public function makeSound(): Implement Method makeSound() ในแต่ละ Class ให้ return เสียงที่แตกต่างกัน

ถ้าเราไม่ Implement makeSound() ใน Class Dog หรือ Cat จะเกิดข้อผิดพลาด:

// สมมติว่าไม่ได้ Implement makeSound() ใน Dog
class Dog extends Animal {
  // ... ไม่มี makeSound() ...
}

$dog = new Dog("Buddy"); // Fatal error: Class Dog contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Animal::makeSound)

PHP จะแจ้งว่า Class Dog มี Abstract Method ที่ยังไม่ได้ Implement และจะต้องถูกประกาศเป็น Abstract Class หรือ Implement Method นั้น

กรณีใช้งานจริง

Abstract Classes มักถูกใช้เพื่อ:

  • กำหนดโครงสร้างพื้นฐาน: สร้าง Class แม่ที่กำหนด Properties และ Methods ที่ Class ลูกจะต้องมี
  • บังคับให้ Implement Methods: ทำให้แน่ใจว่า Class ลูกจะต้อง Implement Methods ที่จำเป็น
  • สร้าง Hierarchy ของ Classes: จัดระเบียบ Classes ที่มีความสัมพันธ์กัน

ตัวอย่าง: ระบบจัดการฐานข้อมูล

เราสามารถสร้าง Abstract Class ชื่อ Database ที่กำหนด Method สำหรับเชื่อมต่อฐานข้อมูล, query ข้อมูล, และปิดการเชื่อมต่อ:

abstract class Database {
  protected $connection;

  abstract public function connect();
  abstract public function query($sql);
  abstract public function close();
}

จากนั้นเราสามารถสร้าง Class ลูกสำหรับแต่ละฐานข้อมูล เช่น MySQL, PostgreSQL, หรือ SQLite:

class MySQLDatabase extends Database {
  public function connect() {
    // โค้ดสำหรับเชื่อมต่อ MySQL
    $this->connection = mysqli_connect("localhost", "username", "password", "database");
    if (!$this->connection) {
      die("Connection failed: " . mysqli_connect_error());
    }
    return true;
  }

  public function query($sql) {
    // โค้ดสำหรับ query ข้อมูลใน MySQL
    $result = mysqli_query($this->connection, $sql);
    return $result;
  }

  public function close() {
    // โค้ดสำหรับปิดการเชื่อมต่อ MySQL
    mysqli_close($this->connection);
  }
}

class PostgreSQLDatabase extends Database {
  public function connect() {
    // โค้ดสำหรับเชื่อมต่อ PostgreSQL
    // ...
  }

  public function query($sql) {
    // โค้ดสำหรับ query ข้อมูลใน PostgreSQL
    // ...
  }

  public function close() {
    // โค้ดสำหรับปิดการเชื่อมต่อ PostgreSQL
    // ...
  }
}

วิธีนี้ทำให้เราสามารถเปลี่ยนชนิดของฐานข้อมูลได้ง่าย โดยไม่ต้องแก้ไขโค้ดส่วนอื่น

ข้อผิดพลาดที่พบบ่อย

  • พยายามสร้าง Object จาก Abstract Class: ไม่สามารถทำได้ จะเกิดข้อผิดพลาด
  • ลืม Implement Abstract Methods: Class ลูกจะต้อง Implement Abstract Methods ทั้งหมด มิฉะนั้น Class ลูกก็จะกลายเป็น Abstract Class ไปด้วย
  • Visibility ไม่ตรงกัน: Visibility ของ Method ที่ Implement ใน Class ลูกจะต้องเหมือนหรือ "กว้างกว่า" (Public > Protected > Private) Visibility ของ Abstract Method ใน Class แม่

ตัวอย่าง:

abstract class ParentClass {
  abstract protected function getValue();
}

class ChildClass extends ParentClass {
  // Fatal error: Access level to ChildClass::getValue() must be protected (as in class ParentClass) or weaker
  public function getValue() {
    return "Hello";
  }
}

ในตัวอย่างนี้ Visibility ของ getValue() ใน ChildClass คือ public ซึ่ง "กว้างกว่า" protected ใน ParentClass ดังนั้นจึงไม่เกิดข้อผิดพลาด แต่ถ้า getValue() ใน ChildClass เป็น private จะเกิดข้อผิดพลาด

สรุป

Abstract Classes เป็นเครื่องมือที่มีประโยชน์ในการกำหนดโครงสร้างและบังคับให้ Class ลูกต้องปฏิบัติตาม ช่วยให้เราสร้างระบบที่ยืดหยุ่นและ maintainable มากขึ้น ในบทต่อไป เราจะเรียนรู้เกี่ยวกับ Static Properties และ Methods ซึ่งเป็นอีกแนวคิดที่สำคัญในการเขียนโปรแกรมเชิงวัตถุ

Office.in.th Custom Service

想基于此结构开发或定制系统?

Office.in.th 承接企业级 Web Application、API Integration 以及政府/企业管理系统的设计与开发,并提供长期支持。

查看软件开发服务