เทมเพลตเป็นพื้นฐานของการเขียนโปรแกรมทั่วไป ซึ่งเกี่ยวข้องกับการเขียนโค้ดในลักษณะที่ไม่ขึ้นกับประเภทใดโดยเฉพาะ
เทมเพลตคือพิมพ์เขียวหรือสูตรสำหรับสร้างคลาสหรือฟังก์ชันทั่วไป คอนเทนเนอร์ไลบรารี เช่น ตัววนซ้ำและอัลกอริธึมเป็นตัวอย่างของการเขียนโปรแกรมทั่วไปและได้รับการพัฒนาโดยใช้แนวคิดเทมเพลต
มีคำจำกัดความเดียวสำหรับแต่ละคอนเทนเนอร์ เช่น 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++ มี "การพิมพ์ภายหลัง" และการเขียนโปรแกรมเมตาของเทมเพลต และสร้างคลาสใหม่สำหรับแต่ละอินสแตนซ์