เทมเพลตเป็นพื้นฐานของการเขียนโปรแกรมทั่วไป ซึ่งเกี่ยวข้องกับการเขียนโค้ดในลักษณะที่ไม่ขึ้นกับประเภทใดโดยเฉพาะ
เทมเพลตคือพิมพ์เขียวหรือสูตรสำหรับสร้างคลาสหรือฟังก์ชันทั่วไป คอนเทนเนอร์ไลบรารี เช่น ตัววนซ้ำและอัลกอริธึมเป็นตัวอย่างของการเขียนโปรแกรมทั่วไปและได้รับการพัฒนาโดยใช้แนวคิดเทมเพลต
มีคำจำกัดความเดียวสำหรับแต่ละคอนเทนเนอร์ เช่น vector แต่เราสามารถกำหนดเวกเตอร์ได้หลายประเภท เช่น vector
โค้ดตัวอย่าง
#include <iostream> #include <string> using namespace std; template <typename T> inline T const& Max (T const& a, T const& b) { return a < b ? b:a; } int main () { int i = 39; int j = 20; cout << "Max(i, j): " << Max(i, j) << endl; double f1 = 13.5; double f2 = 20.7; cout << "Max(f1, f2): " << Max(f1, f2) << endl; string s1 = "Hello"; string s2 = "World"; cout << "Max(s1, s2): " << Max(s1, s2) << endl; return 0; }
ผลลัพธ์
Max(i, j): 39 Max(f1, f2): 20.7 Max(s1, s2): World
ในทางกลับกัน Java เป็น Generics
เมธอด Java Generic และคลาสทั่วไปช่วยให้โปรแกรมเมอร์สามารถระบุได้ด้วยการประกาศเมธอดเดียว ชุดของเมธอดที่เกี่ยวข้อง หรือด้วยการประกาศคลาสเดียว ชุดของประเภทที่เกี่ยวข้อง ตามลำดับ
Generics ยังให้ความปลอดภัยประเภทเวลาคอมไพล์ซึ่งช่วยให้โปรแกรมเมอร์ตรวจจับประเภทที่ไม่ถูกต้องได้ในเวลาคอมไพล์
โดยใช้แนวคิด Java Generic เราอาจเขียนวิธีการทั่วไปสำหรับการเรียงลำดับอาร์เรย์ของวัตถุ จากนั้นเรียกใช้วิธีการทั่วไปด้วยอาร์เรย์จำนวนเต็ม อาร์เรย์คู่ อาร์เรย์สตริง และอื่นๆ เพื่อจัดเรียงองค์ประกอบอาร์เรย์
วิธีการทั่วไป
คุณสามารถเขียนการประกาศวิธีการทั่วไปแบบเดียวที่สามารถเรียกด้วยอาร์กิวเมนต์ประเภทต่างๆ ตามประเภทของอาร์กิวเมนต์ที่ส่งผ่านไปยังเมธอดทั่วไป คอมไพเลอร์จะจัดการการเรียกเมธอดแต่ละเมธอดอย่างเหมาะสม ต่อไปนี้เป็นกฎสำหรับกำหนดวิธีการทั่วไป -
-
การประกาศเมธอดทั่วไปทั้งหมดมีส่วนพารามิเตอร์ประเภทที่คั่นด้วยวงเล็บมุม (<และ>) ที่นำหน้าประเภทการส่งคืนของเมธอด (
ในตัวอย่างถัดไป) -
ส่วนพารามิเตอร์ประเภทแต่ละส่วนมีพารามิเตอร์ประเภทตั้งแต่หนึ่งรายการขึ้นไปโดยคั่นด้วยเครื่องหมายจุลภาค พารามิเตอร์ประเภทหรือที่เรียกว่าตัวแปรประเภทคือตัวระบุที่ระบุชื่อประเภททั่วไป
-
พารามิเตอร์ประเภทสามารถใช้เพื่อประกาศประเภทการส่งคืนและทำหน้าที่เป็นตัวยึดสำหรับประเภทของอาร์กิวเมนต์ที่ส่งผ่านไปยังเมธอดทั่วไป ซึ่งเรียกว่าอาร์กิวเมนต์ประเภทจริง
-
เนื้อหาของเมธอดทั่วไปถูกประกาศเหมือนกับวิธีอื่นๆ โปรดทราบว่าพารามิเตอร์ประเภทสามารถแสดงได้เฉพาะประเภทอ้างอิง ไม่ใช่ประเภทดั้งเดิม (เช่น int, double และ char)
โค้ดตัวอย่าง
public class GenericMethodTest { // generic method printArray public static < E > void printArray( E[] inputArray ) { // Display array elements for(E element : inputArray) { System.out.printf("%s ", element); } System.out.println(); } public static void main(String args[]) { // Create arrays of Integer, Double and Character Integer[] intArray = { 1, 2, 3, 4, 5 }; Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4 }; Character[] charArray = { 'H', 'E', 'L', 'L', 'O' }; System.out.println("Array integerArray contains:"); printArray(intArray); // pass an Integer array System.out.println("\nArray doubleArray contains:"); printArray(doubleArray); // pass a Double array System.out.println("\nArray characterArray contains:"); printArray(charArray); // pass a Character array } }
ผลลัพธ์
Array integerArray contains: 1 2 3 4 5 Array doubleArray contains: 1.1 2.2 3.3 4.4 Array characterArray contains: H E L L O
ตอนนี้ให้เราดูความแตกต่างระหว่างเทมเพลตและชื่อสามัญ ความแตกต่างมีดังนี้ -
-
ใช้ Type-Erasure; สิ่งนี้ทำให้แน่ใจได้ว่ามีการตรวจสอบประเภทที่เข้มงวดยิ่งขึ้นในเวลาคอมไพล์ Generics ใน Java ให้ความปลอดภัยในการคอมไพล์และขจัดความจำเป็นของ typecasting สิ่งนี้มีอยู่ในส่วนหน้าของคอมไพเลอร์จาวาโดยตรงเพื่อให้แน่ใจว่าการลบประเภทนี้เสร็จสิ้น
-
ใน C++ หากใช้เทมเพลต คอมไพเลอร์จะส่งโค้ดเทมเพลตอีกครั้งหลังจากแทนที่พารามิเตอร์ทั่วไปด้วยประเภทที่กำหนด
-
ใน Java แม้ว่าเราต้องระบุประเภทข้อมูล ซึ่งภายในฟังก์ชันที่เรียกใช้โดยใช้อ็อบเจกต์ใดๆ เราไม่จำเป็นต้องพิมพ์แบบเดียวกับ C++ ที่มีประเภทข้อมูลจริง แทนที่จะใช้คลาสแรปเปอร์เพื่อทำสิ่งที่จำเป็น
-
ยาชื่อสามัญของ Java ใช้การตรวจสอบประเภทในช่วงเวลาเริ่มต้น และสร้างรหัสไบต์ที่เทียบเท่ากับรหัสที่ไม่ใช่ทั่วไป C++ มี "การพิมพ์ภายหลัง" และการเขียนโปรแกรมเมตาของเทมเพลต และสร้างคลาสใหม่สำหรับแต่ละอินสแตนซ์