본문으로 건너뛰기

เนื้อหาภาษาไทย / 태국어 콘텐츠

시스템 가이드 검수 완료된 콘텐츠

OOP: Polymorphism

บทความนี้อธิบายถึง Polymorphism ซึ่งเป็นหลักการสำคัญของ OOP ที่ช่วยให้วัตถุต่างชนิดกันสามารถตอบสนองต่อ method เดียวกันด้วยวิธีที่แตกต่างกัน โดยใช้ Method Overri...

OOP: Polymorphism

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

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

Polymorphism มาจากภาษากรีก แปลว่า "หลายรูปแบบ" (many forms) ในบริบทของ OOP, Polymorphism หมายถึง ความสามารถของวัตถุ (Objects) ที่จะตอบสนองต่อ method call เดียวกันด้วยวิธีการที่แตกต่างกัน ขึ้นอยู่กับชนิดของวัตถุนั้นๆ

ลองนึกภาพว่าเรามี Class ชื่อ `Animal` และ Subclass อีกสอง Class คือ `Dog` และ `Cat` ทั้งสาม Class มี method ชื่อ `makeSound()` แต่ละ Class จะ implement `makeSound()` ให้ส่งเสียงที่แตกต่างกันไป: `Animal` อาจจะส่งเสียงทั่วไป, `Dog` อาจจะเห่า, และ `Cat` อาจจะร้องเหมียว นี่คือ Polymorphism ในการปฏิบัติ: วัตถุแต่ละชนิดตอบสนองต่อ method เดียวกันในแบบของตัวเอง

Polymorphism ช่วยให้เราเขียนโค้ดที่สามารถทำงานกับวัตถุหลากหลายชนิดได้โดยไม่ต้องรู้ชนิดของวัตถุเหล่านั้นล่วงหน้า ทำให้โค้ดของเรามีความ generic และ reusable มากขึ้น

Method Overriding

Method Overriding เป็นกลไกที่ใช้ในการ implement Polymorphism ใน PHP เมื่อ Subclass มี method ที่มีชื่อและ signature (parameters) เหมือนกับ method ใน Superclass เราจะเรียกว่า Subclass นั้นทำการ Override method ของ Superclass

เมื่อเราเรียก method ที่ถูก Override บน Object ของ Subclass, PHP จะเรียกใช้ implementation ของ Subclass แทนที่จะเป็นของ Superclass นี่คือหัวใจสำคัญของ Polymorphism

<?php

class Animal {
  public function makeSound() {
    echo "Generic animal sound\n";
  }
}

class Dog extends Animal {
  public function makeSound() {
    echo "Woof!\n";
  }
}

class Cat extends Animal {
  public function makeSound() {
    echo "Meow!\n";
  }
}

$animal = new Animal();
$dog = new Dog();
$cat = new Cat();

$animal->makeSound(); // Output: Generic animal sound
$dog->makeSound();    // Output: Woof!
$cat->makeSound();    // Output: Meow!

// Polymorphism in action
$animals = [$animal, $dog, $cat];

foreach ($animals as $animalInstance) {
  $animalInstance->makeSound(); // Output: Generic animal sound, Woof!, Meow!
}

?>

ในตัวอย่างนี้ `Dog` และ `Cat` Override method `makeSound()` ของ `Animal` เมื่อเราวนลูปผ่าน array `$animals` และเรียก `makeSound()` บนแต่ละ object, output จะแตกต่างกันไปตามชนิดของ object นั้นๆ นี่คือ Polymorphism ที่แสดงให้เห็นถึงความสามารถในการตอบสนองต่อ method เดียวกันด้วยวิธีที่แตกต่างกัน

เหตุผลเชิงออกแบบและ Trade-offs:

  • Trade-off: Method overriding ทำให้เกิดความซับซ้อนในการทำความเข้าใจลำดับการทำงานของโปรแกรม หากมีการ Override method หลายชั้น อาจทำให้ยากต่อการติดตามว่า method ใดถูกเรียกใช้จริง
  • เหตุผลเชิงออกแบบ: Method overriding ช่วยให้เราสามารถปรับเปลี่ยนพฤติกรรมของ Class ที่สืบทอดมาได้โดยไม่ต้องแก้ไขโค้ดของ Superclass ทำให้โค้ดมีความยืดหยุ่นและง่ายต่อการ maintain
  • แนวปฏิบัติที่ดี: ควรใช้ Method overriding อย่างระมัดระวัง และควรมีเอกสารประกอบที่ชัดเจนเพื่ออธิบายการทำงานของ method ที่ถูก Override

Interface and Abstract Classes

Interface และ Abstract Classes เป็นเครื่องมือที่สำคัญในการ implement Polymorphism ใน PHP โดยเฉพาะอย่างยิ่งเมื่อเราต้องการกำหนดสัญญา (contract) ว่า Class ที่ implement Interface หรือ extends Abstract Class จะต้องมี method บางอย่าง

Interface: Interface กำหนดชุดของ method ที่ Class จะต้อง implement แต่ไม่ได้ให้ implementation ใดๆ Class ที่ implement Interface จะต้อง provide implementation ของ method เหล่านั้นทั้งหมด

<?php

interface AnimalInterface {
  public function makeSound();
}

class Dog implements AnimalInterface {
  public function makeSound() {
    echo "Woof!\n";
  }
}

class Cat implements AnimalInterface {
  public function makeSound() {
    echo "Meow!\n";
  }
}

function animalSpeak(AnimalInterface $animal) {
  $animal->makeSound();
}

$dog = new Dog();
$cat = new Cat();

animalSpeak($dog); // Output: Woof!
animalSpeak($cat); // Output: Meow!

?>

ในตัวอย่างนี้ `AnimalInterface` กำหนดว่า Class ที่ implement จะต้องมี method `makeSound()` ฟังก์ชัน `animalSpeak()` รับ parameter เป็น object ที่ implement `AnimalInterface` ทำให้เราสามารถส่ง `Dog` หรือ `Cat` เข้าไปในฟังก์ชันนี้ได้โดยไม่ต้องกังวลว่า object นั้นๆ จะมี method `makeSound()` หรือไม่

Abstract Classes: Abstract Classes คล้ายกับ Interface แต่สามารถมีทั้ง Abstract method (method ที่ไม่มี implementation) และ Concrete method (method ที่มี implementation) Class ที่ extends Abstract Class จะต้อง implement Abstract method ทั้งหมด

<?php

abstract class Animal {
  abstract public function makeSound();

  public function sleep() {
    echo "Zzz...\n";
  }
}

class Dog extends Animal {
  public function makeSound() {
    echo "Woof!\n";
  }
}

class Cat extends Animal {
  public function makeSound() {
    echo "Meow!\n";
  }
}

$dog = new Dog();
$cat = new Cat();

$dog->makeSound(); // Output: Woof!
$cat->makeSound(); // Output: Meow!
$dog->sleep();    // Output: Zzz...

?>

ในตัวอย่างนี้ `Animal` เป็น Abstract Class ที่มี Abstract method `makeSound()` และ Concrete method `sleep()` `Dog` และ `Cat` extends `Animal` และ implement `makeSound()`

เหตุผลเชิงออกแบบและ Trade-offs:

  • Trade-off: การใช้ Interface และ Abstract Class เพิ่มความซับซ้อนให้กับโครงสร้างของโปรแกรม อาจทำให้ต้องเขียนโค้ดมากขึ้น
  • เหตุผลเชิงออกแบบ: Interface และ Abstract Class ช่วยให้เรากำหนดสัญญา (contract) ที่ชัดเจนระหว่าง Class ต่างๆ ทำให้โค้ดมีความ consistent และง่ายต่อการ maintain
  • แนวปฏิบัติที่ดี: ควรใช้ Interface เมื่อต้องการกำหนดชุดของ method ที่ Class จะต้อง implement โดยไม่ต้องสนใจ implementation, และควรใช้ Abstract Class เมื่อต้องการกำหนด method ที่มี implementation บางส่วนและบังคับให้ Subclass implement method ที่เหลือ

สรุป

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

Method Overriding, Interface และ Abstract Classes เป็นเครื่องมือที่สำคัญในการ implement Polymorphism ใน PHP โดยแต่ละเครื่องมือมีข้อดีและข้อเสียที่แตกต่างกันไป การเลือกใช้เครื่องมือที่เหมาะสมจะช่วยให้เราเขียนโค้ดที่มีประสิทธิภาพและ maintainable มากขึ้น

ในบทถัดไป เราจะมาเรียนรู้เกี่ยวกับ Abstract Classes และ Interfaces ในรายละเอียดมากขึ้น

Office.in.th Custom Service

이 구조를 바탕으로 시스템을 개발하거나 맞춤 변경하고 싶으신가요?

Office.in.th는 엔터프라이즈 웹 애플리케이션, API 연동, 공공/민간 업무 관리 시스템을 설계·개발하며 장기 지원을 제공합니다.

소프트웨어 개발 서비스 보기