Swift Academy · Lección

Fundamentos de upcasting y downcasting

Pase entre tipos de superclase y subclase.

Lección 1 de 413 pasos

Fundamentos de upcasting y downcasting es una lección gratuita de Swift Academy en CoddyKit. Esta es la lección 1 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Swift Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Swift Academy incluye 4 lecciones en total.

Introducción a la conversión de tipos

La conversión de tipos permite tratar una instancia como si fuera de otro tipo dentro de su jerarquía de clases. Consiste en comprobar o cambiar el tipo estático, no en convertir los datos.

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())

Una jerarquía de clases

La conversión de tipos requiere una jerarquía. En este caso, Dog y Cat heredan de Animal. Un Dog es un 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)

Conversión ascendente con as

La conversión ascendente trata una instancia de una subclase como si fuera de su superclase. Siempre se realiza correctamente, por lo que se usa el operador as sin modificadores.

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)

Por qué usar la conversión ascendente

La conversión ascendente resulta útil para almacenar distintas subclases juntas, por ejemplo, en un solo array cuyo tipo sea la superclase común.

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) }

La conversión ascendente siempre es segura

Como toda instancia de una subclase también es una instancia válida de su superclase, el compilador acepta as en las conversiones ascendentes sin riesgo de que fallen.

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)

Pérdida de acceso tras una conversión ascendente

Una vez almacenada como el tipo de la superclase, solo puede llamar a los miembros de esa superclase. El método específico de Dog, bark(), permanece oculto hasta que realice una conversión descendente.

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

Introducción a la conversión descendente

La conversión descendente funciona en la dirección contraria: trata una referencia de la superclase como una subclase específica para recuperar sus miembros. Puede fallar, por lo que requiere as? o 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())
}

Por qué puede fallar la conversión descendente

El compilador no puede garantizar que un Animal determinado sea realmente un Dog. Podría ser un Cat. Por esa incertidumbre, las conversiones descendentes deben comprobarse.

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)

Conversión descendente en un bucle

Un patrón habitual consiste en recorrer un array de la superclase y convertir cada elemento para tratar las subclases de manera diferente.

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()) }
}

Resumen de las conversiones ascendente y descendente

La conversión ascendente (as) se dirige hacia el tipo base y siempre se realiza correctamente. La conversión descendente (as? o as!) se dirige hacia un tipo específico y puede fallar.

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")

Conversión solo dentro de una jerarquía

Solo puede realizar conversiones entre tipos relacionados de la misma jerarquía. Los tipos no relacionados no se pueden convertir entre sí.

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)

Comprobación rápida

Recuerde en qué dirección de conversión siempre se realiza correctamente.

Resumen: conversiones ascendente y descendente

Ha aprendido que las conversiones funcionan dentro de una jerarquía de clases, que la conversión ascendente con as hacia el tipo base siempre se realiza correctamente, y que la conversión descendente hacia una subclase específica puede fallar y, por tanto, requiere los operadores comprobados que se presentan a continuación.

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) }
}
Gratis para empezar

Aprende Swift con un tutor de IA — gratis

Escribe y ejecuta código real en tu navegador, obtén ayuda instantánea de un tutor de IA disponible 24/7 y continúa donde lo dejaste en la web o en la aplicación.

Cursos
122
Lecciones
409

Preguntas frecuentes

¿La lección «Fundamentos de upcasting y downcasting» es gratis?

Sí — el texto completo de «Fundamentos de upcasting y downcasting» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Swift Academy, actualiza a CoddyKit PRO. El curso de Swift Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Fundamentos de upcasting y downcasting»?

Pase entre tipos de superclase y subclase. Practicas Swift Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Swift Academy?

No se requiere experiencia previa. Swift Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 1 de 4.

¿Cuánto tiempo toma la lección «Fundamentos de upcasting y downcasting»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Swift Academy?

Sí. Cada lección de Swift Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Fundamentos de upcasting y downcasting
  2. Conversión condicional con as?
  3. Conversión forzada con as! y sus riesgos
  4. Comprobación de tipos con is
← Volver a Swift Academy