In Swift, บทความทั้งหมด, ภาษาคอมพิวเตอร์

AnyObject และ Any

จากที่ผ่านมาเราได้ทราบว่า การเก็บค่าลงในอาร์เรย์ จะต้องเป็น Type เดียวกันเสมอ เช่น

แต่ถ้าในบางครั้ง เราอาจจำเป็นต้องเก็บค่าลงในอาร์เรย์ที่มี Type ต่างกัน เช่น เก็บค่าตัวเลขจาก Int กับข้อความจาก String รวมกันลงในอาร์เรย์ เราจึงต้องใช้งาน Type แบบพิเศษ ซึ่งมีอยู่ 2 แบบ ได้แก่ AnyObject และ Any

  • AnyObject คือ Instance ที่เป็น Object ซึ่งหมายถึง Instance ที่สร้างมาจาก Class
  • Any คือ Instance ที่สร้างมาจาก Type อะไรก็ได้

ตัวอย่างการใช้งาน AnyObject

ต่อไปนี้เป็นตัวอย่างการใช้งาน AnyObject โดยจะสร้าง Object ขึ้นมาจาก 3 คลาสที่แตกต่างกัน แล้วนำเอาไปใส่ไว้ในอาร์เรย์ซึ่งมี Type เป็น แบบ AnyObject

  • บรรทัดที่ 10 สร้าง Instance จากคลาส FirstClass
  • บรรทัดที่ 11 สร้าง Instance จากคลาส SecondClass
  • บรรทัดที่ 12 สร้าง Instance จากคลาส ThirdClass
  • บรรทัดที่ 13 นำเอา Instance ที่สร้างมาจากคลาสต่างกัน มาเก็บไว้ในอาร์เรย์เดียวกัน ดังนั้น Type ที่อยู่ในอาร์เรย์จึงใช้เป็น AnyObject

ตัวอย่างการใช้งาน Any

Any สามารถใช้งานได้กับ Type อะไรก็ได้มาผสมกัน ซึ่งแตกต่างจาก AnyObject ที่ต้องเป็น Instance ที่สร้างมาจากคลาสเท่านั้น

จากโค้ตตัวอย่างด้านบน ได้ประกาศอาร์เรย์ในแบบ Any ซึ่งหมายความว่า เราจะนำ Type อะไรก็ได้มาใส่ในอาร์เรย์ม่ว่าจะเป็น Int, Double, String, Tuple หรือ Type อื่นๆ

วิธีตรวจสอบ Type

สำหรับวิธีตรวจสอบว่า Instance มี Type เป็นอะไร เราจะใช้ is (เรียกว่า Type checking operator) ซึ่งในภาษา Swift สามารถใช้ is เพื่อตรวจสอบ Type รวมถึง Type ที่เป็น Subclass ได้ดังนี้

instanceName is Type

ต่อไปนี้เป็นตัวอย่างการใช้งาน is เพื่อตรวจสอบ Type ซึ่งเมื่อทราบว่าเป็น Type อะไรแล้ว ก็จะสามารถเลือกใช้  Method หรือนำเอาค่า Property จาก Type นั้นๆ มาใช้งานได้

  • บรรทัดที่ 13 นำเอา Instance ที่สร้างมาจากคลาส มาเก็บลงในอาร์เรย์
  • บรรทัดที่ 14 วนลูปเข้าไปยังทุกๆ ค่าในอาร์เรย์ โดยทุกๆ ครั้งที่วนลูปจะเก็บค่าลงใน item
  • บรรทัดที่ 15 ตรวจสอบว่า item มี Type เป็น FirstClass หรือไม่ โดยใช้ is
  • บรรทัดที่ 16 ทำการ DownCasting จาก AnyObject ให้กลายเป็น FirstClass แล้วเก็บค่า Instance ไปยัง first
  • บรรทัดที่ 17 พิมพ์ข้อความออกมาที่คอนโซล โดย first.firstProperty คือ การนำค่าพร็อบเพอตี้จาก  FirstClass ออกมาใช้งาน

Type Checking คือ ความสามารถที่ Swift สามารถตรวจสอบลำดับชั้นของ Class ได้ (หรือที่เรียกว่า Class Hierarchy) เมื่อเราสร้าง Instance ขึ้นมาจาก Class ด้วยคุณสมบัติ Type Checking ภาษา Swift ก็จะทราบว่า Instance ที่สร้างขึ้นมานั้น มีเป็น Type อะไร และมีลำดับชั้นอย่างไร

ต่อไปนี้ผมได้กำหนด Class ขึ้นมา 4 คลาสได้แก่ Human, Thai, Japanese และ Chinese โดยกำหนดให้ Human เป็น SuperClass ส่วน Thai, Japanese และ Chinese เป็น SubClass ดังรูป

รูป

ด้วยคุณสมบัติของ Type Checking ซึ่งสามารถตรวจสอบโครงสร้างลำดับชั้นได้ ดังนั้นเมื่อเราสร้าง Instance ขึ้นจากคลาส Thai ภาษา Swift ก็จะทราบว่า Instance นี้เป็น SubClass ของ Human โดยอัตโนมัติ

  • บรรทัดที่ 1 กำหนดคลาส Human ซึ่งเป็น SuperClass
  • บรรทัดที่ 10 สร้างคลาส Thai ให้เป็น SubClass ของคลาส Human
  • บรรทัดที่ 25 สร้าง Instance ขึ้นมาใหม่จากคลาส Thai ดังนั้นด้วยคุณสมบัติ Type Checking ภาษา Swift จะทราบโครงสร้างลำดับชั้นของ Instance นี้โดยอัตโนมัติ

รู้จักกับ UpCasting และ DownCasting

จากที่ผ่านมาได้กล่าวถึงคุณสมบัติ Type Checking ซึ่งเป็นคุณสมบัติที่ Swift สามารถตรวจสอบลำดับชั้นของ Instance ที่สร้างมาจาก Class ใดๆ ได้ นอกจากคุณสมบัติดังกล่าวภาษา ​Swift ยังมีคุณสมบัติในการเปลี่ยน Type ภายในลำดับชั้นได้อีกด้วย ซึ่งวิธีการเปลี่ยนประเภท Type ที่อยู่ในลำดับชั้นเรียกว่า Type Casting ซึ่งมีรูปแบบการใช้งานอยู่ 2 แบบ ดังนี้

UpCasting คือการเปลี่ยน Instance ของ SubClass ให้กลายเป็น Instance ของ SuperClass  เช่น เปลี่ยนจาก Thai ให้กลายเป็น Human เป็นต้น

รูป

DownCasting คือการทดลองเปลี่ยน Instance ของ SuperClass ให้กลายเป็น Instance ของ SubClass เช่น การเปลี่ยนจาก Human ให้กลายเป็น Thai เป็นต้น

รูป

วิธีใช้งาน UpCasting

UpCasting เป็นความสามารถในการเข้าไปยัง Instance แล้วเปลี่ยนไปใช้ Instance ของ Type ที่เป็นของ SuperClass แทน

การ UpCasting จะใช้ as (เรียกว่า type cast operator) เพื่อนำเอา Instance จากการ UpCasting มาใช้งาน ซึ่งมีรูปแบบ ดังนี้

instanceName as SuperClassType

เนื่องจาก Swift ทราบลำดับชั้นของคลาสโดยอัตโนมัติอยู่แล้ว เช่น ทราบว่า Thai เป็น SubClass ของคลาส Human ดังนั้น การ UpCasting เปลี่ยนจาก Thai ให้กลายเป็น Human จึงทำได้ทันที ดังตัวอย่างต่อไปนี้

  • บรรทัดที่ 15 สร้าง Instance โดยตั้งชื่อว่า thaiPeople ซึ่งสร้างมาจากคลาส Thai
  • บรรทัดที่ 16 ใช้วิธี UpCasting เพื่อเปลี่ยน thaiPeople ให้กลายเป็นคลาส Human แล้วนำผลลัพธ์ไปเก็บไว้ยัง man

วิธีใช้งาน DownCasting

DownCasting เป็นความสามารถในการเข้าไปยัง Instance แล้วพยายาม (Try) เข้าใช้งาน Instance นั้นๆ โดยเปลี่ยนไปใช้ Instance ของ Type ที่เป็นของ Subclass แทน

เนื่องจาก การ DownCasting อาจสำเร็จหรือไม่สำเร็จก็ได้ ผลลัพธ์ที่ได้จาก DownCasting จึงเป็น Optional ดังนั้นเราจึงต้องใช้ as? หรือ as!  ซึ่งแบ่งวิธีใช้งานออกเป็น 2 รูปแบบ ดังนี้

แบบแรก คือเราไม่มั่นใจว่า DownCasting จะสำเร็จหรือไม่ ซึ่งผลลัพธ์จากการ DownCasting อาจเป็น nil ดังนั้น เราจึงใช้เครื่องหมาย as? ดังนี้

instanceName as? SubClassType

แต่หากเรามั่นใจว่า การ DownCasting สำเร็จแน่นอน เราสามารถใช้ as! ได้ แต่วิธีนี้ไม่นิยมนัก เพราะหากผลลัพธ์การ DownCasting เป็น nil ก็จะเกิด error ทันที

instanceName as! SubClassType

ต่อไปนี้เป็นตัวอย่างการ DownCasting โดยทดลองเปลี่ยน Instance ที่สร้างจากคลาส Human ให้กลายเป็นคลาส Thai และทดลอง DownCasting ให้กลายเป็นคลาส Japanese

  • บรรทัดที่ 20 สร้าง Instance โดยตั้งชื่อว่า thaiPeople ซึ่งสร้างมาจากคลาส Thai
  • บรรทัดที่ 21 ใช้วิธี UpCasting เพื่อเปลี่ยน thaiPeople ให้กลายเป็นคลาส Human แล้วนำผลลัพธ์ไปเก็บไว้ยัง people ซึ่งการ UpCasting สามารถทำได้เลยจึงใช้ as
  • บรรทัดที่ 22 ทดลอง DownCasting โดยเปลี่ยน people ให้กลายเป็นคลาส Thai ซึ่งผลลัพธ์ที่ได้จะนำไปเก็บยัง downCastInstance01 โดยผลลัพธ์จาก DownCasting จะได้กลับมาเป็น Optional  แต่ในกรณีนี้เรามั่นใจว่า DownCasting สำเร็จ (ทราบอยู่แล้วว่า people สร้างมาจากคลาส Thai) เราจึงใช้ as!
  • บรรทัดที่ 23 ทดลอง DownCasting โดยเปลี่ยน people ให้กลายเป็นคลาส Japanese ซึ่งทำไม่ได้เนื่องจาก people สร้างมาจากคลาส Thai ดังนั้นผลลัพธ์จึงได้เป็น nil กลับมา

Instance ที่มาจาก SuperClass เดียวกัน

เมื่อเรานำเอา Instance ที่สร้างมาจากคลาสที่ต่างกันมาจับใส่ลงในอาร์เรย์ หาก Instance เหล่านั้นมาจาก SuperClass เดียวกัน ภาษา Swift ฉลาดพอที่จะนำเอา Type ของ SuperClass มาใช้งานอัตโนมัติ ดังตัวอย่างต่อไปนี้

  • บรรทัดที่ 1 กำหนดคลาส Human
  • บรรทัดที่ 10 กำหนดคลาส Thai ซึ่งเป็น SubClass ของคลาส Human
  • บรรทัดที่ 15 กำหนดคลาส Japanese ซึ่งเป็น SubClass ของคลาส Human
  • บรรทัดที่ 20 สร้าง Instance จากคลาส Thai แล้วเก็บค่าไว้ที่ people01
  • บรรทัดที่ 21 สร้าง Instance จากคลาส Japanese เก็บค่าไว้ที่ people02
  • บรรทัดที่ 22 นำเอา Instance มาใส่รวมกันไว้ในอาร์เรย์ ภาษา Swift ก็จะทราบว่าทั้ง people01 และ people02 มี SuperClass เดียวกันคือคลาส Human ดังนั้น Type ของอาร์เรย์นี้จึงเป็น [Human] โดยอัตโนมัติ

จากตัวอย่างข้างบน เราสามารถระบุ Type ในอาร์เรย์เป็น [Human] หรือจะใช้ [AnyObject] แทนก็ได้ ดังนี้

  • บรรทัดที่ 22 กำหนด Type ของอาร์เรย์เป็น [Human]
  • บรรทัดที่ 23 กำหนด Type ของอาร์เรย์เป็น [AnyObject]

 

ติดต่อเรา

หากสมาชิกท่านใดพบปัญหา หรือมีข้อสงสัยประการใด สามารถติชม หรือเสนอแนะ มายังเว็บมาสเตอร์ได้ตลอดเวลานะครับ

Not readable? Change text. captcha txt
0

Start typing and press Enter to search