Protocolos y programación orientada a protocolos
Los protocolos definen capacidades, no jerarquías. Con extensiones de protocolo consigues comportamiento compartido sin herencia: el estilo idiomático de Swift.
Si en otros lenguajes la reutilización se basa en heredar de clases, en Swift se basa en protocolos. Un protocolo es un contrato: “quien cumpla esto, puede hacer aquello”. Es más flexible que la herencia y funciona con structs, enums y clases por igual.
- Definir protocolos y conformar a ellos.
- Extensiones de protocolo con implementaciones por defecto.
- Programación orientada a protocolos (POP).
- Protocolos del sistema: Identifiable, Codable, Comparable.
Un protocolo es un contrato
Define qué debe ofrecer un tipo, sin decir cómo:
protocol Describible {
var descripcion: String { get }
func resumen() -> String
}
Cualquier tipo puede conformar al protocolo implementando lo que pide:
struct Libro: Describible {
let titulo: String
var descripcion: String { "Libro: \(titulo)" }
func resumen() -> String { descripcion }
}
Un struct, un enum o una class pueden conformar al mismo protocolo. La capacidad no depende de la jerarquía de tipos.
Extensiones de protocolo: comportamiento compartido
Aquí está el superpoder. Puedes dar una implementación por defecto a los métodos de un protocolo mediante una extensión:
extension Describible {
func resumen() -> String {
"→ \(descripcion)" // implementación por defecto para TODOS
}
}
struct Pelicula: Describible {
let titulo: String
var descripcion: String { "Película: \(titulo)" }
// no hace falta implementar resumen(): hereda el de la extensión
}
Ahora cualquier tipo que conforme a Describible obtiene resumen() gratis, y puede sobreescribirlo si quiere.
Con clases, para compartir código heredas de una superclase, y acabas con jerarquías rígidas y frágiles (el “problema del diamante”, clases base infladas…). Con protocolos + extensiones, un tipo compone capacidades: conforma a Identifiable, a Codable, a Comparable, y obtiene comportamiento de cada uno, sin heredar de nada. Esto es la programación orientada a protocolos, la filosofía central de Swift. Piensa en “qué puede hacer” este tipo, no “qué es”.
Protocolos del sistema que usarás siempre
Identifiable
Da a un tipo un id único. SwiftUI lo exige para listas: cada fila necesita identidad.
Codable
Convierte a/desde JSON automáticamente. Clave para redes (Nivel 5).
Comparable
Permite ordenar (<, sorted()) tus tipos.
Equatable / Hashable
Comparar por igualdad y usar en Sets y claves de Dictionary.
struct Tarea: Identifiable, Codable {
let id = UUID()
var titulo: String
var completada = false
}
Con solo declarar la conformidad, Swift sintetiza el código por ti (el id, la codificación JSON, la comparación…). Escribes el contrato; el compilador rellena lo mecánico.
Los protocolos brillan junto a los genéricos (próxima lección): puedes escribir una función que funcione con “cualquier tipo que sea Comparable”, o “cualquier Codable”. El protocolo es la restricción que da poder a lo genérico.
- Define un protocolo
Saludablecon un métodosaludar(). - Dale una implementación por defecto con una extensión.
- Haz que una struct conforme sin implementar el método (usa el default) y otra que lo sobreescriba.
- Crea una struct
Productoque conforme aIdentifiableyCodablecon unid = UUID().