Polymorphism เป็นแนวคิดพื้นฐานในการเขียนโปรแกรมเชิงวัตถุที่ช่วยให้วัตถุประเภทต่างๆ ถือเป็นวัตถุประเภทฐานทั่วไป ช่วยให้อินเทอร์เฟซเดียวเพื่อแสดงการใช้งานที่เป็นรูปธรรมหลายอย่าง โดยให้ความยืดหยุ่นและความสามารถในการขยายในการออกแบบโค้ด ในบทความนี้ เราจะสำรวจแนวคิดเรื่องความหลากหลายใน C# ผ่านตัวอย่างต่างๆ เพื่อทำความเข้าใจการประยุกต์ใช้ในทางปฏิบัติได้ดียิ่งขึ้น
1. ความแตกต่างกับมรดก:
โดยทั่วไปความหลากหลายจะเกิดขึ้นได้จากการสืบทอด โดยที่คลาสที่ได้รับมาสามารถใช้เป็นอินสแตนซ์ของคลาสพื้นฐานได้ ซึ่งช่วยให้อินเทอร์เฟซที่สอดคล้องกันสำหรับวัตถุประเภทต่างๆ มาอธิบายสิ่งนี้ด้วยตัวอย่าง:
using System; // Base class representing a Shape class Shape { public virtual void Draw() { Console.WriteLine("Drawing a shape."); } } // Derived classes Circle and Rectangle inheriting from Shape class Circle : Shape { public override void Draw() { Console.WriteLine("Drawing a circle."); } } class Rectangle : Shape { public override void Draw() { Console.WriteLine("Drawing a rectangle."); } } class Program { static void Main() { Shape shape1 = new Circle(); Shape shape2 = new Rectangle(); shape1.Draw(); // Output: Drawing a circle. shape2.Draw(); // Output: Drawing a rectangle. } }
ในตัวอย่างนี้ เรามีคลาสพื้นฐาน Shape
ที่มีเมธอดเสมือน Draw()
ซึ่งจากนั้นจะถูกแทนที่โดยคลาส Circle
และ Rectangle
เมธอด Draw()
ถูกเรียกใช้บนออบเจ็กต์ประเภทพื้นฐาน Shape
และดำเนินการเมธอดแทนที่ที่เหมาะสมจากคลาสที่ได้รับตามประเภทรันไทม์ของออบเจ็กต์ สิ่งนี้เรียกว่าความหลากหลายแบบไดนามิกหรือความหลากหลายแบบรันไทม์
2. ความแตกต่างกับอินเทอร์เฟซ:
อินเทอร์เฟซยังมีบทบาทสำคัญในการบรรลุความหลากหลายโดยจัดทำสัญญาที่หลายคลาสสามารถนำมาใช้ได้ มาสำรวจตัวอย่างด้วยอินเทอร์เฟซ:
using System; // Interface representing a Printable object public interface IPrintable { void Print(); } // Classes Document and Image implementing IPrintable class Document : IPrintable { public void Print() { Console.WriteLine("Printing a document."); } } class Image : IPrintable { public void Print() { Console.WriteLine("Printing an image."); } } class Program { static void Main() { IPrintable printable1 = new Document(); IPrintable printable2 = new Image(); printable1.Print(); // Output: Printing a document. printable2.Print(); // Output: Printing an image. } }
ในตัวอย่างนี้ เรามีอินเทอร์เฟซ IPrintable
พร้อมเมธอด Print()
ซึ่งใช้งานโดยคลาส Document
และ Image
เราสร้างอินสแตนซ์ของคลาสเหล่านี้และเก็บไว้ในตัวแปรประเภท IPrintable
เมื่อเราเรียกใช้เมธอด Print()
กับตัวแปรเหล่านี้ มันจะดำเนินการใช้งานที่เหมาะสมที่ได้รับจากคลาสที่เป็นรูปธรรม
3. ความแตกต่างด้วยวิธีโอเวอร์โหลด:
ความหลากหลายยังเกิดขึ้นได้จากการโอเวอร์โหลดวิธีการ ซึ่งมีการกำหนดวิธีการหลายวิธีที่มีชื่อเดียวกันแต่มีพารามิเตอร์ต่างกัน ลองดูตัวอย่าง:
using System; class MathOperations { public int Add(int num1, int num2) { return num1 + num2; } public double Add(double num1, double num2) { return num1 + num2; } } class Program { static void Main() { MathOperations math = new MathOperations(); int result1 = math.Add(5, 10); // Output: 15 double result2 = math.Add(3.5, 2.5); // Output: 6.0 Console.WriteLine("Result 1: " + result1); Console.WriteLine("Result 2: " + result2); } }
ในตัวอย่างนี้ คลาส MathOperations
กำหนดสองวิธีด้วยชื่อเดียวกัน Add
แต่มีประเภทพารามิเตอร์ต่างกัน (จำนวนเต็มและสองเท่า) เมื่อเราเรียกใช้เมธอด Add
ด้วยประเภทพารามิเตอร์ที่แตกต่างกัน วิธีการโอเวอร์โหลดที่เหมาะสมจะถูกเรียกใช้ตามประเภทข้อมูลของอาร์กิวเมนต์ สิ่งนี้เรียกว่าความหลากหลายทางเวลาคอมไพล์หรือความหลากหลายแบบคงที่
สรุป: Polymorphism เป็นแนวคิดที่ทรงพลังที่ช่วยให้โค้ดสามารถนำกลับมาใช้ใหม่ได้ มีความยืดหยุ่น และขยายได้ในการเขียนโปรแกรมเชิงวัตถุ ด้วยการใช้ประโยชน์จากการสืบทอด อินเทอร์เฟซ และการโอเวอร์โหลดเมธอด C# ช่วยให้นักพัฒนาสามารถเขียนโค้ดที่สะอาด เป็นโมดูล และบำรุงรักษาได้ง่าย การทำความเข้าใจและการใช้ความหลากหลายอย่างมีประสิทธิภาพสามารถนำไปสู่แอปพลิเคชันที่แข็งแกร่งและปรับขนาดได้