ปกติเวลาที่เขียนคลาสขึ้นมาคลาสหนึ่งจะต้องกำหนดไปเลยว่าคลาสนั้นจะให้มีอินพุตชนิดของข้อมูลเป็นประเภทไหน แล้วทำงานอะไรบ้าง เช่นคลาส A กำหนดว่าจะให้มีอินพุตเป็นจำนวนเต็ม เอาไปทำงาน พอมีคลาสอื่นมาประกาศอ็อปเจ็คประเภทคลาส A ก็จะต้องใส่อินพุตเป็นจำนวนเต็มเท่านั้น ไม่อย่างนั้นจะ error แต่บางครั้งการทำงานของคลาส A มีประโยชน์กับคลาสอื่นที่ไม่ได้ใช้อินพุตแบบจำนวนเต็มก็ทำให้ต้องสร้างคลาสใหม่แล้วก็ไปก็อบข้อมูลของคลาส A มาเปลี่ยนชนิดข้อมูลจาก Integer ไปเป็นอย่างอื่น
รูป 14-1
สร้างคลาสแบบปกติโดยมีตัวแปร a กับ b และมีเมท็อดสำหรับคืนค่าของตัวแปรออกไป โดยคลาสนี้กำหนดให้ภายในคลาสมีข้อมูลประเภท int ซึ่งคลาสใดๆที่เรียกใช้อ็อปเจ็คของคลาสนี้จะต้องใช้ข้อมูลแบบ int เหมือนกัน
รูป14-2
นี่คือตัวอย่างของคลาสปกติที่ได้เขียนๆกันอยู่แล้วคือคลาส NormalClass ให้ชนิดของข้อมูลเป็น int ดังนั้นเวลาที่คลาส CallNormal เรียกอ็อปเจ็คของคลาส NormalClass มาใช้ตอนเรียกคอนสตรัคเตอร์ก็ต้องใส่ข้อมูลเป็น int ถ้าใส่ double เช่น 5.5 ก็จะ error
การใช้งานเจอเนริค
ปัญหาของคลาสแบบคลาสแบบข้างบนก็คือถ้าสมมติต้องการใช้งานกับข้อมูลแบบประเภทอื่นต้องเขียนคลาสขึ้นมาใหม่ซึ่งทำให้ยุ่งยากก็สามารถใช้หลักการของเจอเนริคมาใช้ได้ โดยเจอเนริคคือเขียนคลาสที่ทำให้สามารถใส่ข้อมูลเป็นประเภทไหนก็ได้ วิธีประกาศเจอเนริคทำแบบนี้
class ชื่อคลาส< ประเภทข้อมูล>
ส่วนการใช้งานเขียนแบบนี้
ชื่อคลาส<ประเภทข้อมูล> ชื่อตัวแปร = new ชื่อคลาส<ประเภทข้อมูล>(พารามิเตอร์);
รูป 14-3
เอาคลาส NormalClass มาเขียนใหม่ในรูปแบบของเจอเนริค
บรรทัดที่ 3 : สร้างคลาสชื่อ Generic ตามด้วยเครื่องหมาย <> โดยให้ข้างในเป็นประเภทของข้อมูล ในที่นี้ให้
เป็นประเภท T
บรรทัดที่ 4 : ประกาศตัวแปร a ของคลาส เป็นประเภท T ที่ให้เป็นประเภท T เพราะว่าเวลาที่มีการเรียกใช้อ็อป
เจ็คของเจอเนริคแล้วมีการกำหนดว่า T เป็นอะไร ตัวแปรจะได้เป็นข้อมูลประเภทนั้นไปด้วย
บรรทัดที่ 7 : สร้างคอนสตรัคเตอร์(เมท็อดที่ชื่อเหมือนคลาส) รับพารามิเตอร์สองตัวเป็นประเภท T เหมือนเดิม
แล้วตั้งค่าให้ตัวแปร x กับ y
บรรทัดที่ 12 : สร้างเมท็อดสำหรับดูค่าของตัวแปร a ประเภทของตัวแปรที่จะคืนค่าออกก็ต้องเป็น T ด้วย
รูป14-4
บรรทัดที่ 8 : เรียกใช้อ็อปเจ็คของ Generic โดยกำหนดประเภทของข้อมูลเป็นจำนวนเต็ม Integer (กำหนดใน
<>) เมื่อให้อ็อปเจ็คนี้รับข้อมูลประเภอจำนวนเต็มในพารามิเตอร์จึงสามารถใส่เลขจำนวนเต็ม 5 กับ 7 ได้
บรรทัดที่ 9-10 : ให้ตัวแปร x และ y ซึ่งเป็นตัวแปรประเภท int เก็บค่าของอ็อปเจ็ค g ที่เรียกมาจากเมท็อดของ
คลาส Generic
บรรทัดที่ 11-12 : แสดงค่าของ x y ออกมาดู
บรรทัดที่ 15 : ประกาศตัวแปร w กับ z เป็น double
บรรทัดที่ 16 : เรียกใช้อ็อปเจ็คประเภทGeneric อีd ให้ชื่อว่า g2 กำหนดเป็นประเภท double เพราะฉะนั้นอ็อป
เจ็คนี้จะเก็บ double
ผลลัพธ์ที่ได้
รูป 14-5
จะเห็นว่าด้วยการใช้เจอเนริคจะทำให้เวลาต้องการเอาคลาสไปใช้งานซ้ำๆสามารถทำได้อย่างง่ายดายไม่ต้องคอยเปลี่ยนประเภทของข้อมูล แต่อย่างไรก็ตามหากใส่ประเภทข้อมูลประเภทไหนในเจอเนริคแล้วก็ต้องใช้ข้อมูลแบบนั้นตลอด
เจอเนริคกับอ็อปเจ็ค
ภายในเครื่องหมาย<> จะต้องใส่คลาสลงไปเท่านั้น ไม่สามารถใส่พวกประเภทข้อมูลแบบ primitive ได้เช่น int, float, long, double เพราะจะทำให้ error
เช่น Gen<int> Obj = new Gen<int>(53);
แบบนี้ไม่ได้เพราะ int เป็น ประเภทข้อมูลแบบ primitive ส่วน Integer เป็นคลาสของข้อมูลประเภท int ดังนั้นหากต้องให้เจอเนริคเป็น int ต้องใส่คลาส Integer ลงในเครื่องหมาย <>
ไม่ใช้เจอเนริคได้ไหม แบบจะ cast ข้อมูลเอาได้ไหม – ได้ แต่มันก็จะยุ่งยากอีกเรื่องต้อง cast เพราะถ้าลืมมันจะคอมไพล์ไม่ผ่านซึ่งถ้าใช้เจอเนริคแต่แรกก็จบปัญหานี้แล้ว
เจอเนริคแบบรับพารามิเตอร์มากกว่าหนึ่ง
เจอเนริคไม่จำเป็นต้องมีพารามิเตอร์แค่ตัวเดียวก็ได้ มีสองหรือมากกว่าก็ได้ โดยเขียนแบบนี้
class ชื่อคลาส< ประเภทข้อมูล1, ประเภทข้อมูล2 >
ส่วนการใช้งานเขียนแบบนี้
ชื่อคลาส<ประเภทข้อมูล1, ประเภทข้อมูล2 > ชื่อตัวแปร
= new ชื่อคลาส<ประเภทข้อมูล1, ประเภทข้อมูล2 > (พารามิเตอร์1, พารามิเตอร์2);
รูป 14-6
แก้ไขจากคลาสเจอเนริคเดิม แต่คราวนี้ให้เจอเนริคไม่จำเป็นต้องเป็นข้อมูลประเภทเดียวแต่เป็นสองประเภทคือ T กับ V หลังจากนั้นให้ a กับ b เป็นตัวแปรประเภท T และ V ตามลำดับ หลังจากนั้นก็เขียนคอนสตรัคเตอร์และเมท็อด
รูป14-7
เมื่อทำการ new อ็อปเจ็คของคลาส Generic ขึ้นมาคราวนี้จะต้องใส่ พารามิเตอร์สำหรับประเภทข้อมูลให้ครบทั้งสอง โดยบรรทัดที่ 8 ทำการใช้อ็อปเจ็คของ Generic และให้ประเภทของข้อมูลหรือไทป์พารามิเตอร์(type parameter)เป็น double และ String ตามลำดับ ดังนั้นตรงพารามิเตอร์ของคอนสตรัคเตอร์ก็ต้องใส่ข้อมูลเป็น double และ String ตามลำดับด้วย
ผลลัพธ์ดังภาพ
รูป14-8
คอนสตรัคเตอร์ของคลาสเจอเนริค
จากตัวอย่างจะเห็นว่าการประกาศใช้งานคอนสตรัคเตอร์คลาสที่เป็นคลาสเจอเนริคไม่ต้องมีไทป์พารามิเตอร์ต่อท้ายแบบว่า public Generic<T>( ) { } แต่สามารถเขียนว่า public Generic( ) { } ได้เลย หรือจะมีพารามิเตอร์ public Generic(T x ) { } ก็ได้
ArrayList<E>
อาร์เรย์ลิสต์เป็นเจอเนริคแบบหนึ่งที่มีประโยชน์สำหรับอาเรย์มาก เพราะปกติอาร์เรย์ต้องมีการกำหนดขนาดและใช้ได้ตามขนาดที่กำหนดเท่านั้น แต่อาร์เรย์ลิสต์คืออาร์เรย์ที่ไม่ต้องกำหนดขนาดเพราะสามารถขยายขนาดได้เอง เมื่อมีข้อมูลที่มีขนาดเกินก็จะทำการขยายขนาดตัวเอง
การสร้างอาร์เรย์ลิสต์
ArrayList<ประเภทข้อมูลที่จะเก็บในอาร์เรย์ลิสต์> ชื่อตัวแปร
= new ArrayList<ประเภทข้อมูลที่จะเก็บในอาร์เรย์ลิสต์>(ขนาดของอาร์เรย์ลิสต์);
การใช้งานอาร์เรย์ลิสต์ต้อง import java.util.ArrayList;
ตัวอย่างการสร้างอาร์เรย์ลิสต์
ArrayList<String> list = new ArrayList<String>(10);
นี่คือการสร้างอาร์เรย์ลิสต์ชื่อลิสต์สำหรับเก็บสตริง10ช่อง อย่าลืมว่าภายใน<> เก้บข้อมูลแบบ primitive ไม่ได้
เมท็อดของอาร์เรย์ลิสต์
เพิ่มข้อมูล add เช่น list.add(“cat”); เพิ่มคำว่า cat
เรียกข้อมูล get เช่น list.get(list.size()-1); ดูข้อมูลตัวสุดท้าย
ลบข้อมูล remove เช่น list.remove(0); ลบข้อมูลช่องแรกของอาร์เรย์ลิสต์
ดูขนาดของอาร์เรย์ลิสต์ size เช่น list.size();
รูป14-9
ตัวอย่างการใช้ ArrayList โดยใช้ลูป for เป็นข้อมูลในลิสต์11ตัว
บรรทัดที่ 17 : เพิ่มข้อมูลลงใน list ข้อมูลจะไปปรากฏที่ท้ายสุดของอาร์เรย์ ปริ้นมาดูว่าจริงไหม
บรรทัดที่ 20 : ขอดูข้อมูลตำแหน่งสุดท้ายต้อง size-1 เพราะอาร์เรย์เริ่มต้นที่ 0
บรรทัดที่ 22 : ลบข้อมูลตำแหน่งที่ size-5 ก็นับมาจากตัวสุดท้าย 5 ตัวคือต้องลบ 7 ออก ก็ปริ้นออกมาดูอีก
รูป14-10
บรรทัดแรกวนลูปใส่ list จากตอนแรก list มี 0 ช่อง ก็กลายเป็น 11 ช่อง
บรรทัดที่สองเพิ่มข้อมูล 66 ต้องไปอยู่ท้ายสุด
บรรทัดที่สามดูข้อมูลตัวสุดท้ายเท่ากับ 66
บรรทัดที่สี่ลบเลข7
Tag ที่น่าสนใจ: java generics generic_class type_parameters object-oriented_programming data_types integer double type_casting type_parameterization
หากมีข้อผิดพลาด/ต้องการพูดคุยเพิ่มเติมเกี่ยวกับบทความนี้ กรุณาแจ้งที่ http://m.me/Expert.Programming.Tutor
085-350-7540 (DTAC)
084-88-00-255 (AIS)
026-111-618
หรือทาง EMAIL: NTPRINTF@GMAIL.COM