พื้นฐานการแปลงชนิดขึ้นและลง
แปลงระหว่างชนิดคลาสแม่และคลาสลูก
พื้นฐานการแปลงชนิดขึ้นและลง เป็นบทเรียน Swift Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Swift Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Swift Academy มีบทเรียนทั้งหมด 4 บทเรียน
ภาพรวมการแคสต์ชนิดข้อมูล
การแคสต์ชนิดข้อมูล ช่วยให้คุณมองอินสแตนซ์เป็นชนิดอื่นภายในลำดับชั้นของคลาสได้ นี่คือการตรวจสอบหรือเปลี่ยนชนิดข้อมูลเชิงสถิต ไม่ใช่การแปลงข้อมูล
class Animal {
let name: String
init(name: String) { self.name = name }
}
class Dog: Animal {
func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
func meow() -> String { return name + " says Meow" }
}
let d = Dog(name: "Rex")
print(d.bark())ลำดับชั้นของคลาส
การแคสต์ต้องอาศัยลำดับชั้น ในที่นี้ Dog และ Cat ต่างสืบทอดจาก Animal ดังนั้น Dog จึงเป็น Animal
class Animal {
let name: String
init(name: String) { self.name = name }
}
class Dog: Animal {
func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
func meow() -> String { return name + " says Meow" }
}
let pet: Animal = Dog(name: "Rex")
print(pet.name)การแคสต์ขึ้น
การแคสต์ขึ้น คือการมองอินสแตนซ์ของคลาสย่อยเป็นคลาสแม่ การแคสต์นี้สำเร็จเสมอ จึงใช้ตัวดำเนินการ as แบบปกติ
class Animal {
let name: String
init(name: String) { self.name = name }
}
class Dog: Animal {
func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
func meow() -> String { return name + " says Meow" }
}
let dog = Dog(name: "Rex")
let asAnimal = dog as Animal
print(asAnimal.name)เหตุผลที่ควรแคสต์ขึ้น
การแคสต์ขึ้นมีประโยชน์สำหรับจัดเก็บคลาสย่อยต่าง ๆ ไว้ด้วยกัน เช่น ในอาร์เรย์เดียวที่กำหนดชนิดเป็นคลาสแม่ร่วมกัน
class Animal {
let name: String
init(name: String) { self.name = name }
}
class Dog: Animal {
func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
func meow() -> String { return name + " says Meow" }
}
let zoo: [Animal] = [Dog(name: "Rex"), Cat(name: "Mia")]
for a in zoo { print(a.name) }การแคสต์ขึ้นปลอดภัยเสมอ
เนื่องจากอินสแตนซ์ของคลาสย่อยทุกตัวเป็นอินสแตนซ์ของคลาสแม่ที่ถูกต้องด้วย คอมไพเลอร์จึงยอมรับ as สำหรับการแคสต์ขึ้นโดยไม่มีความเสี่ยงที่จะล้มเหลว
class Animal {
let name: String
init(name: String) { self.name = name }
}
class Dog: Animal {
func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
func meow() -> String { return name + " says Meow" }
}
let cat = Cat(name: "Mia")
let animal = cat as Animal
print("Treated as Animal:", animal.name)การเข้าถึงที่หายไปหลังแคสต์ขึ้น
เมื่อจัดเก็บในชนิดของคลาสแม่แล้ว คุณจะเรียกใช้ได้เฉพาะสมาชิกของคลาสแม่เท่านั้น ส่วน bark() ที่เฉพาะกับ Dog จะถูกซ่อนไว้จนกว่าคุณจะแคสต์ลง
class Animal {
let name: String
init(name: String) { self.name = name }
}
class Dog: Animal {
func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
func meow() -> String { return name + " says Meow" }
}
let a: Animal = Dog(name: "Rex")
print(a.name)
// a.bark() would not compile hereเบื้องต้นเกี่ยวกับการแคสต์ลง
การแคสต์ลง ทำในทิศทางตรงกันข้าม คือมองการอ้างอิงของคลาสแม่เป็นคลาสย่อยเฉพาะ เพื่อเข้าถึงสมาชิกของคลาสนั้นอีกครั้ง การดำเนินการนี้อาจล้มเหลว จึงต้องใช้ as? หรือ as!
class Animal {
let name: String
init(name: String) { self.name = name }
}
class Dog: Animal {
func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
func meow() -> String { return name + " says Meow" }
}
let a: Animal = Dog(name: "Rex")
if let dog = a as? Dog {
print(dog.bark())
}เหตุผลที่การแคสต์ลงอาจล้มเหลว
คอมไพเลอร์ไม่สามารถรับประกันได้ว่า Animal ที่กำหนดจะเป็น Dog จริง อาจเป็น Cat ก็ได้ ความไม่แน่นอนนี้ทำให้ต้องตรวจสอบการแคสต์ลง
class Animal {
let name: String
init(name: String) { self.name = name }
}
class Dog: Animal {
func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
func meow() -> String { return name + " says Meow" }
}
let a: Animal = Cat(name: "Mia")
let maybeDog = a as? Dog
print("Is it a Dog?", maybeDog != nil)การแคสต์ลงในลูป
รูปแบบที่ใช้บ่อยคือ วนซ้ำอาร์เรย์ของคลาสแม่ แล้วแคสต์สมาชิกแต่ละตัวลงเพื่อจัดการคลาสย่อยแต่ละแบบแตกต่างกัน
class Animal {
let name: String
init(name: String) { self.name = name }
}
class Dog: Animal {
func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
func meow() -> String { return name + " says Meow" }
}
let zoo: [Animal] = [Dog(name: "Rex"), Cat(name: "Mia")]
for a in zoo {
if let dog = a as? Dog { print(dog.bark()) }
if let cat = a as? Cat { print(cat.meow()) }
}สรุปการแคสต์ขึ้นเทียบกับการแคสต์ลง
การแคสต์ขึ้น (as) เคลื่อนไปหาชนิดพื้นฐานและสำเร็จเสมอ การแคสต์ลง (as? หรือ as!) เคลื่อนไปหาชนิดเฉพาะและอาจล้มเหลว
class Animal {
let name: String
init(name: String) { self.name = name }
}
class Dog: Animal {
func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
func meow() -> String { return name + " says Meow" }
}
let d = Dog(name: "Rex")
let up = d as Animal
let down = up as? Dog
print(up.name, down?.bark() ?? "no")การแคสต์ทำได้เฉพาะภายในลำดับชั้นเดียวกัน
คุณสามารถแคสต์ระหว่างชนิดข้อมูลที่เกี่ยวข้องกันภายในลำดับชั้นเดียวกันเท่านั้น ชนิดข้อมูลที่ไม่เกี่ยวข้องกันไม่สามารถแคสต์ถึงกันได้
class Animal {
let name: String
init(name: String) { self.name = name }
}
class Dog: Animal {
func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
func meow() -> String { return name + " says Meow" }
}
let a: Animal = Dog(name: "Rex")
print(a is Animal)
print(a is Dog)ตรวจสอบอย่างรวดเร็ว
โปรดทบทวนว่าการแคสต์ในทิศทางใดสำเร็จเสมอ
สรุป: การแคสต์ขึ้นและการแคสต์ลง
คุณได้เรียนรู้ว่าการแคสต์ทำงานภายในลำดับชั้นของคลาส การแคสต์ขึ้นด้วย as ไปยังชนิดพื้นฐานสำเร็จเสมอ และการแคสต์ลงไปยังคลาสย่อยเฉพาะอาจล้มเหลว จึงต้องใช้ตัวดำเนินการตรวจสอบที่จะกล่าวถึงต่อไป
class Animal {
let name: String
init(name: String) { self.name = name }
}
class Dog: Animal {
func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
func meow() -> String { return name + " says Meow" }
}
let pets: [Animal] = [Dog(name: "Rex"), Cat(name: "Mia")]
for p in pets {
if let d = p as? Dog { print(d.bark()) } else { print(p.name) }
}คำถามที่พบบ่อย
บทเรียน “พื้นฐานการแปลงชนิดขึ้นและลง” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “พื้นฐานการแปลงชนิดขึ้นและลง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Swift Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Swift Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “พื้นฐานการแปลงชนิดขึ้นและลง”
แปลงระหว่างชนิดคลาสแม่และคลาสลูก คุณปฏิบัติ Swift Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Swift Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Swift Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน
บทเรียน “พื้นฐานการแปลงชนิดขึ้นและลง” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Swift Academy นี้ได้ไหม
ได้ บทเรียน Swift Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- พื้นฐานการแปลงชนิดขึ้นและลง
- การแปลงชนิดแบบมีเงื่อนไขด้วย as?
- การแปลงชนิดแบบบังคับด้วย as! และความเสี่ยง
- การตรวจสอบชนิดด้วย is