วันพุธที่ 19 กุมภาพันธ์ พ.ศ. 2568

[PHP] การสืบทอดคลาส (Class Inheritance) : เข้าใจง่าย ใช้งานได้จริง!

การสืบทอดคลาส (Inheritance) คืออะไร?

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

ใน PHP (และภาษา OOP อื่น ๆ) การสืบทอดคลาสช่วยให้เราสร้างคลาสใหม่จากคลาสที่มีอยู่แล้ว โดยไม่ต้องเขียนโค้ดใหม่ทั้งหมด คลาสใหม่ (เรียกว่า คลาสลูก หรือ Subclass) จะได้รับคุณสมบัติ (Properties) และพฤติกรรม (Methods) จากคลาสเดิม (เรียกว่า คลาสแม่ หรือ Superclass) แบบอัตโนมัติ

พูดง่าย ๆ คือ เราไม่ต้องเริ่มจากศูนย์ แต่สามารถใช้ของที่มีอยู่แล้วมาต่อยอดได้เลย!

 

ทำไมต้องใช้การสืบทอดคลาส?

1. ลดโค้ดซ้ำซ้อน (Code Reusability) ถ้าเรามีโค้ดที่ใช้บ่อย ๆ ในหลายคลาส แทนที่จะก็อปปี้โค้ดไปวางซ้ำ ๆ เราสามารถให้คลาสลูกสืบทอดจากคลาสแม่เพื่อใช้โค้ดเดิมได้เลย

2. แก้ไขง่ายขึ้น (Easier Maintenance) ถ้าต้องการแก้ไขพฤติกรรมของคลาสหลาย ๆ ตัวที่คล้ายกัน เราแค่แก้ที่คลาสแม่ คลาสลูกทั้งหมดก็จะได้รับการเปลี่ยนแปลงโดยอัตโนมัติ

3. โครงสร้างโปรแกรมชัดเจน (Better Code Structure) ทำให้โปรแกรมมีโครงสร้างที่เป็นลำดับชั้น เข้าใจง่าย เช่น มีคลาส Animal เป็นคลาสแม่ และมี Dog, Cat, Bird เป็นคลาสลูก

4. รองรับการเขียนโปรแกรมเชิงวัตถุ (OOP Principles) ช่วยให้เราใช้หลักการ OOP อย่าง Encapsulation, Inheritance, และ Polymorphism ได้เต็มที่ 

 

ตัวอย่างโค้ด PHP: การสืบทอดคลาสแบบง่าย ๆ

มาดูกันว่าการสืบทอดคลาสใน PHP ทำงานอย่างไร

<?php
// คลาสแม่ (Superclass)
class Animal {
    public $name;

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

    public function makeSound() {
        return "เสียงสัตว์";
    }
}

// คลาสลูก (Subclass) สืบทอดจาก Animal
class Dog extends Animal {
    public function makeSound() {
        return "โฮ่ง โฮ่ง!";
    }
}

// ใช้งานจริง
$dog = new Dog("บ๊อบบี้");
echo $dog->name; // บ๊อบบี้
echo "<br>";
echo $dog->makeSound(); // โฮ่ง โฮ่ง!
?>


อธิบายโค้ด:

  • คลาส Animal เป็นคลาสแม่ มีคุณสมบัติ $name และเมธอด makeSound()
  • คลาส Dog เป็นคลาสลูก ใช้ extends เพื่อสืบทอดจาก Animal และเขียน makeSound() ใหม่ (Override)
  • ตอนสร้างอ็อบเจ็กต์ Dog เราสามารถใช้ $dog->name และ $dog->makeSound() ได้เลย!

 

parent:: เรียกใช้เมธอดจากคลาสแม่

บางครั้งเราต้องการใช้เมธอดของคลาสแม่ในคลาสลูก เช่น เราอยากให้ makeSound() ของ Dog ใช้เสียงของ Animal แล้วเติมคำเพิ่ม 

<?php
class Animal {
    public function makeSound() {
        return "เสียงสัตว์ทั่วไป";
    }
}

class Dog extends Animal {
    public function makeSound() {
        return parent::makeSound() . " และเสียงของหมาคือ โฮ่ง โฮ่ง!";
    }
}

$dog = new Dog();
echo $dog->makeSound(); // เสียงสัตว์ทั่วไป และเสียงของหมาคือ โฮ่ง โฮ่ง!
?>


อธิบายโค้ด:

  • parent::makeSound() คือการเรียกใช้เมธอด makeSound() จากคลาสแม่ แล้วเติมคำเพิ่ม

 

protected และ private มีผลกับการสืบทอดยังไง?

  • public = ใช้ได้ทุกที่ (ทั้งในคลาสแม่ คลาสลูก และจากภายนอก)
  • protected = ใช้ได้ในคลาสแม่และคลาสลูกเท่านั้น
  • private = ใช้ได้เฉพาะในคลาสที่ประกาศเท่านั้น (คลาสลูกมองไม่เห็น!)

มาดูตัวอย่างกัน 

<?php
class Animal {
    public $name = "สัตว์"; // ใช้ได้ทุกที่
    protected $color = "น้ำตาล"; // ใช้ได้ในคลาสแม่และลูก
    private $age = 5; // ใช้ได้แค่ในคลาสนี้เท่านั้น

    public function getAge() {
        return $this->age;
    }
}

class Dog extends Animal {
    public function getColor() {
        return $this->color; // ใช้ได้ เพราะเป็น protected
    }

    public function getAgeFromParent() {
        // return $this->age; //  Error! เพราะ age เป็น private
        return $this->getAge(); // ใช้ผ่านเมธอด public ของคลาสแม่ได้
    }
}

$dog = new Dog();
echo $dog->name; // ใช้ได้
// echo $dog->color; // Error! เพราะเป็น protected
// echo $dog->age; // Error! เพราะเป็น private
echo $dog->getColor(); // ใช้ได้
echo $dog->getAgeFromParent(); // ใช้ได้
?>


final ป้องกันการสืบทอดและ Override

ถ้าต้องการห้ามไม่ให้มีคลาสลูกสืบทอดจากคลาสแม่ ให้ใช้ final หน้า class

final class Animal {
    // โค้ดในคลาส
}

// class Dog extends Animal {} //  Error! เพราะ Animal เป็น final

หรือหากต้องการห้าม Override เมธอด ให้ใช้ final หน้า function

class Animal {
    final public function makeSound() {
        return "เสียงสัตว์ทั่วไป";
    }
}

class Dog extends Animal {
    // public function makeSound() {} //  Error! เพราะเมธอด makeSound() เป็น final
}
 

สรุปแนวคิดสำคัญเกี่ยวกับการสืบทอดคลาสใน PHP

  • ใช้ extends เพื่อให้คลาสลูกสืบทอดจากคลาสแม่
  • คลาสลูกได้รับทุกอย่างจากคลาสแม่ (ยกเว้น private)
  • ใช้ parent::method() เรียกเมธอดจากคลาสแม่
  • ใช้ protected เพื่อให้ใช้ได้ในคลาสแม่และลูก แต่ไม่ให้ใช้จากภายนอก
  • ใช้ final ถ้าต้องการห้ามสืบทอดหรือห้าม Override

การสืบทอดคลาสทำให้โค้ดสะอาดขึ้น ง่ายต่อการบำรุงรักษา และรองรับหลักการ OOP อย่างแท้จริง! ถ้าใครยังไม่ได้ลองใช้ในโปรเจกต์ของตัวเอง ลองเอาไปปรับใช้ดูนะ รับรองว่าชีวิตนักพัฒนาจะง่ายขึ้นแน่นอน!

 

 

 

 

ไม่มีความคิดเห็น:

แสดงความคิดเห็น