Polymorphism เป็นหลักการสำคัญหนึ่งในแนวคิดของการเขียนโปรแกรมแบบวัตถุ (Object-Oriented Programming - OOP) ที่เปิดโอกาสให้ objects ต่างๆ สามารถถูกดำเนินงานผ่าน interface เดียวกัน แต่วิธีการทำงานภายในอาจแตกต่างกันออกไป ในภาษา Fortran ซึ่งเป็นหนึ่งในภาษาโปรแกรมที่เก่าแก่ที่สุดและยังคงมีการใช้งานอย่างแพร่หลายในสาขาวิทยาศาสตร์และวิศวกรรม ก็รองรับการใช้งาน OOP และ polymorphism ขอบคุณการอัปเดตในมาตรฐาน Fortran 90 เป็นต้นไป ต่อไปนี้คือตัวอย่าง code ทั้ง 3 ตัวอย่างที่จะช่วยให้คุณเข้าใจเกี่ยวกับการใช้งาน polymorphism ใน Fortran:
module shapes_mod
implicit none
private
public :: shape
type, abstract :: shape
contains
procedure(shape_area), deferred :: area
end type shape
abstract interface
function shape_area(this) result(area)
import :: shape
class(shape), intent(in) :: this
real :: area
end function shape_area
end interface
end module shapes_mod
module circle_mod
implicit none
public :: circle
type, extends(shape) :: circle
real :: radius
contains
procedure :: area => circle_area
end type circle
contains
function circle_area(this) result(area)
class(circle), intent(in) :: this
real :: area
area = 3.14159 * this%radius**2
end function circle_area
end module circle_mod
program test_polymorphism
use shapes_mod
use circle_mod
implicit none
class(shape), allocatable :: my_shape
real :: a
allocate(circle :: my_shape, source=circle(radius=1.0))
a = my_shape%area()
print *, "Area of shape: ", a
end program test_polymorphism
ในตัวอย่างนี้ `shape` คือ abstract type ที่มี deferred ฟังก์ชัน `area` ซึ่งไม่ได้ถูกนิยามไว้ จากนั้น `circle` คือ type ที่ extend มาจาก `shape` และ implement ฟังก์ชัน `area` ในฟังก์ชัน `test_polymorphism` เราสร้างตัวแปร `my_shape` ที่เป็นแบบ `shape` นั่นคือ polymorphism ที่ทำให้ `my_shape` สามารถเป็น object ประเภทใดก็ได้ที่ extend มาจาก `shape` และเรา allocate ให้เป็น `circle` สุดท้ายเราจะเรียก use ฟังก์ชัน `area` ของ `circle` ผ่าน `my_shape`.
module rectangle_mod
implicit none
public :: rectangle
type, extends(shape) :: rectangle
real :: width, height
contains
procedure :: area => rectangle_area
end type rectangle
contains
function rectangle_area(this) result(area)
class(rectangle), intent(in) :: this
real :: area
area = this%width * this%height
end function rectangle_area
end module rectangle_mod
ตัวอย่างนี้แสดงการสร้าง `rectangle` ที่เป็น derived type จาก `shape` เหมือนกับ `circle` ที่ปรากฏในตัวอย่างแรก และเราก็มีการ override ฟังก์ชัน `area` ของมัน.
program test_polymorphism_advanced
use shapes_mod
use circle_mod
use rectangle_mod
implicit none
class(shape), allocatable :: my_shapes(:)
integer :: i
real :: total_area
! สร้าง array ของ shapes
allocate(my_shapes(2))
allocate(circle :: my_shapes(1), source=circle(radius=1.0))
allocate(rectangle :: my_shapes(2), source=rectangle(width=3.0, height=4.0))
total_area = 0.0
do i = 1, size(my_shapes)
total_area = total_area + my_shapes(i)%area()
end do
print *, "Total area of shapes: ", total_area
end program test_polymorphism_advanced
ในตัวอย่างสุดท้ายนี้, เราได้ใช้ polymorphism ในเชิงปฏิบัติมากขึ้น โดยการสร้าง array ของ shapes ที่มีทั้ง `circle` และ `rectangle`. ระหว่าง loop, เราสามารถเรียกการคำนวณพื้นที่ (`area`) ผ่านตัวแปร `my_shapes` ที่เป็น abstract base type, แต่การทำงานจริงของฟังก์ชันจะขึ้นอยู่กับ type ของ object ที่แท้จริงของแต่ละ element.
ในโลกจริง, polymorphism นี้มีประโยชน์มากในซอฟต์แวร์ที่ต้องการ flexibility หรือในสถานการณ์ที่ components เดียวกันอาจมีการทำงานที่แตกต่างกันไปใน contexts ต่างๆ เช่น ในการพัฒนา simulation สำหรับประเมิน behavior ของวัสดุต่างๆ ที่มีคุณสมบัติทางกายภาพแตกต่างกัน, หรือในกระบวนการตัดสินใจอัตโนมัติซึ่งอาจต้องใช้โมเดลที่พฤติกรรมแตกต่างกันออกไปเพื่อจัดการกับสถานการณ์ที่หลากหลาย.
สำหรับท่านที่สนใจในการเริ่มต้นหรือพัฒนาทักษะการเขียนโปรแกรมของท่าน การเรียนรู้เกี่ยวกับ OOP และพื้นฐานของภาษาโปรแกรมต่างๆ รวมทั้ง Fortran เป็นสิ่งสำคัญไม่แพ้กัน ที่ EPT (Expert-Programming-Tutor) มีคอร์สเรียนและเมนเทอร์ที่พร้อมส่งผ่านความรู้และประสบการณ์ในระดับมืออาชีพ มาเริ่มต้นก้าวแรกของการเป็นโปรแกรมเมอร์พร้อมกับเราที่ EPT วันนี้!
หมายเหตุ: ข้อมูลในบทความนี้อาจจะผิด โปรดตรวจสอบความถูกต้องของบทความอีกครั้งหนึ่ง บทความนี้ไม่สามารถนำไปใช้อ้างอิงใด ๆ ได้ ทาง EPT ไม่ขอยืนยันความถูกต้อง และไม่ขอรับผิดชอบต่อความเสียหายใดที่เกิดจากบทความชุดนี้ทั้งทางทรัพย์สิน ร่างกาย หรือจิตใจของผู้อ่านและผู้เกี่ยวข้อง
หากมีข้อผิดพลาด/ต้องการพูดคุยเพิ่มเติมเกี่ยวกับบทความนี้ กรุณาแจ้งที่ http://m.me/Expert.Programming.Tutor
085-350-7540 (DTAC)
084-88-00-255 (AIS)
026-111-618
หรือทาง EMAIL: NTPRINTF@GMAIL.COM