polymorphism หมายถึงการมีได้หลายรูปแบบ ในภาษาจาวาตัวอย่างของการมีได้หลายรูปแบบ เช่น เมธอดที่รองรับชนิดของข้อมูลที่แตกต่างกันได้ เช่น เมธอด println() หรือการสร้างออบเจกต์ด้วยพารามิเตอร์ที่แตกต่างกัน เป็นต้น
ในทางทฤษฎี polymorphism แบ่งออกเป็น Ad-hoc polymorphism, Subtype polymorphism และ Parametric polymorphism
Ad-hoc polymorphism หมายถึง ฟังก์ชันที่สามารถนำไปใช้กับอาร์กิวเมนต์ประเภทต่างๆ ได้ แต่จะมีพฤติกรรมแตกต่างกันไปตามประเภทของอาร์กิวเมนต์ที่ใช้ สำหรับในภาษาจาวาคือการทำเมธอดโอเวอร์โหลด
Subtype polymorphism หมายถึง การใช้อินสแตนซ์ของคลาสย่อย (sub-class) เมื่อมีการอนุญาตในอินสแตนซ์ของคลาสพื้นฐาน (base-class) หรือให้เข้าใจง่ายๆคือ ในภาษาจาวาจะเป็นการสร้างออบเจกต์โดยกำหนดชนิดของตัวแปรเป็น base-classs แต่สร้างออบเจกต์ด้วย sub class เช่น เรามี base-class เป็นคลาส Account และมี sub-class เป็นคลาส SavingAccount ดังนั้นการใช้ subtype polymorphism จะเป็นดังตัวอย่างด้านล่าง
Account variable = new SavingAccount();
Parametric polymorphism หมายถึงการเขียนโปรแกรมโดยไม่ระบุชนิดของข้อมูลและโปรแกรมสามารถใช้ได้กับทุกชนิดของข้อมูล สำหรับในภาษาจาวาคือความสามารถที่เรียกว่า generics
ในมุมมองของภาษาจาวามี polymorphism สองแบบคือ แบบ static (เวลาคอมไพล์) ทำได้โดยวิธีการโอเวอร์โหลด และแบบ dynamic (รันไทม์) ทำได้โดยการสืบทอดคลาสและโอเวอร์ไรด์เมธอด ตัวอย่างดานล่างเป็นตัวอย่างแบบ dynamic ซึ่งในการใช้งานโปรแกรม เมธอด getFileInfo() ในคลาส ImageFile จะถูกเรียกใช้งานเพราะว่าออบเจกต์ถูกสร้างโดยการอ้างอิง sub-class แม้ว่าตัวแปรจะอ้างอิง base-class ก็ตาม
class File {
protected String fullName;
// constructor with a single parameter
// getters and setters
public void printFileInfo() {
String info = this.getFileInfo(); // here is polymorphic behavior!!!
System.out.println(info);
}
protected String getFileInfo() {
return “File: ” + fullName;
}
}
class ImageFile extends File {
protected int width;
protected int height;
protected byte[] content;
// constructor
// getters and setters
@Override
protected String getFileInfo() {
return String.format(“Image: %s, width: %d, height: %d”, fullName, width, height);
}
}
===================================================
File img = new ImageFile(“/path/to/file/img.png”, 480, 640, someBytes); // สร้างอออบเจกต์โดยตัวแปรกำหนดชนิดของข้อมูลเป็น base-class แต่สร้างออบเจกต์จาก sub-class
img.printFileInfo(); // It prints “Image: /path/to/file/img.png, width: 480, height: 640” เมื่อมีการใช้งาน เมธอด getFileInfo() ในคลาส ImageFile จะถูกเรียกใช้งานเพราะว่าออบเจกต์ถูกสร้างโดยการอ้างอิง sub-class