0Pricing
Swift Academy · บทเรียน

พื้นฐานการแปลงชนิดขึ้นและลง

แปลงระหว่างชนิดคลาสแม่และคลาสลูก

พื้นฐานการแปลงชนิดขึ้นและลง เป็นบทเรียน 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. พื้นฐานการแปลงชนิดขึ้นและลง
  2. การแปลงชนิดแบบมีเงื่อนไขด้วย as?
  3. การแปลงชนิดแบบบังคับด้วย as! และความเสี่ยง
  4. การตรวจสอบชนิดด้วย is
← กลับไปที่ Swift Academy