Protocol é um conjunto de requisitos (propriedades e métodos) que um tipo que adota o protocolo deve atender. Em Swift, os protocolos são o elemento central da Programação Orientada a Protocolos (POP), permitindo polimorfismo sem herança. De acordo com Swift.org (2025), os protocolos são usados em 85% dos tipos da biblioteca padrão do Swift. Em Objective-C, @protocol desempenha um papel semelhante, mas com uma limitação — apenas para classes.
Principais conclusões
Protocol em Swift é uma interface abstrata que define requisitos que um tipo deve satisfazer. Um protocolo pode exigir propriedades (com getter/setter), métodos (de instância e de tipo), inicializadores e subscripts. Ao contrário das classes, os protocolos podem ser adotados por estruturas, enumerações e classes — proporcionando flexibilidade indisponível em linguagens puramente baseadas em classes.
protocol Drawable {
var boundingRect: CGRect { get }
mutating func draw(in context: CGContext)
}
struct Circle: Drawable {
var center: CGPoint
var radius: CGFloat
var boundingRect: CGRect {
CGRect(x: center.x - radius, y: center.y - radius,
width: radius * 2, height: radius * 2)
}
func draw(in context: CGContext) {
context.addEllipse(in: boundingRect)
}
}A estrutura Circle adota o protocolo Drawable, fornecendo a propriedade boundingRect e o método draw(in:). Graças ao protocolo, qualquer forma que implemente Drawable pode ser tratada de forma uniforme — isto é polimorfismo sem herdar de uma classe base comum.
Protocol-Oriented Programming (POP) é um paradigma introduzido pela Apple na WWDC 2015 como alternativa à herança baseada em classes. No POP, os protocolos são a principal ferramenta de abstração e as extensões de protocolo fornecem implementações padrão. Isso resolve o problema da «herança diamante» e permite estender tipos existentes sem modificar o código fonte.
| Aspecto | POP (Orientado a Protocolos) | OOP (Baseado em Classes) |
|---|---|---|
| Unidade de abstração | Protocol | Classe base |
| Mecanismo de reutilização | Protocol extension | Herança |
| Value types | Suportados (struct) | Apenas reference types |
| Adoção múltipla | Protocol composition | Herança múltipla (não em Swift) |
| Risco de acoplamento | Baixo (acoplamento fraco) | Alto (hierarquia rígida) |
De acordo com o blog da Apple Swift (2025), as estruturas representam 70% dos tipos em aplicações Swift modernas. POP é uma razão chave para essa mudança: os protocolos permitem que as estruturas obtenham comportamento polimórfico sem mudar para classes.
Os protocolos Swift ocupam uma posição intermediária entre as interfaces Java e as classes abstratas C++. Eles podem conter implementações (através de extensões), mas não podem ter estado (propriedades armazenadas). Vamos examinar as diferenças entre três linguagens.
| Característica | Swift Protocol | Java Interface | C++ Abstract Class |
|---|---|---|---|
| Implementação de métodos | Sim (extension) | Sim (default methods) | Sim |
| Propriedades armazenadas | Não | Não | Sim |
| Value types | Sim | Não | Não |
| Implementação múltipla | Sim | Sim | Sim |
| Inicializadores | Sim (requisitos) | Não | Sim |
Diferença chave: Swift Protocol pode exigir inicializadores e subscripts, o que não está disponível em Java Interface. No entanto, um protocolo não pode armazenar estado — isto continua sendo responsabilidade do tipo que adota o protocolo.
Associated Type (tipo associado) é um tipo genérico dentro de um protocolo que é concretizado pelo tipo que o adota. Isso permite criar protocolos type-safe sem especificar um tipo de dados concreto. Os tipos associados trabalham em conjunto com os genéricos do Swift.
protocol Container {
associatedtype Item
var count: Int { get }
mutating func append(_ item: Item)
subscript(i: Int) -> Item { get }
}
struct IntStack: Container {
var items: [Int] = []
var count: Int { items.count }
typealias Item = Int
mutating func append(_ item: Int) {
items.append(item)
}
subscript(i: Int) -> Int {
items[i]
}
}
func sum<C: Container>(_ container: C) -> C.Item where C.Item: Numeric {
// corpo da função
}Container é um protocolo com associatedtype Item. IntStack o implementa especificando typealias Item = Int. A função genérica sum usa uma cláusula where para trabalhar apenas com contêineres numéricos. Os tipos associados tornam os protocolos genéricos sem perder a segurança de tipos.
Protocol composition — combinação de vários protocolos através do operador &. Um tipo que está em conformidade com uma composição deve implementar todos os protocolos combinados. Isso substitui a herança múltipla, ausente em Swift, e permite especificar com precisão os requisitos dos parâmetros de função.
protocol Named { var name: String { get } }
protocol Aged { var age: Int { get } }
struct Person: Named, Aged {
let name: String
let age: Int
}
func greet(_ entity: Named & Aged) {
print("Olá, \(entity.name), idade \(entity.age)!")
}
// Protocol extension — implementação padrão
extension Named {
func introduce() {
print("Meu nome é \(name)")
}
}Protocol extension fornece implementações de métodos padrão. Um tipo que adota o protocolo pode sobrescrever o método da extensão — nesse caso, sua própria implementação é chamada. Este é o mecanismo pelo qual Swift implementa métodos opcionais sem @objc.
@protocol em Objective-C é o predecessor do Swift Protocol, mas com limitações significativas. Os protocolos Objective-C estão disponíveis apenas para classes (não para estruturas ou enumerações) e usam despacho dinâmico através de passagem de mensagens. Os métodos podem ser @required (padrão) ou @optional.
@protocol Loggable
@required
- (void)logMessage: (NSString *)message;
@optional
- (NSString *)logPrefix;
@end
@interface ConsoleLogger : NSObject
@end
@implementation ConsoleLogger
- (void)logMessage: (NSString *)message {
NSLog(@"[LOG] %@", message);
}
@endAo contrário do Swift, os protocolos Objective-C não suportam tipos associados, genéricos, extensões de protocolo ou value types. Eles permanecem como um mecanismo de abstração baseado em classes, enquanto o Swift Protocol é uma ferramenta de polimorfismo completa para todos os tipos.
Perguntas frequentes
Protocol não pode armazenar estado (propriedades armazenadas) — apenas requisitos de propriedades. Uma classe abstrata pode conter campos de dados. Um protocolo pode ser adotado por estruturas e enumerações, enquanto uma classe abstrata só pode ser subclassificada por classes. Em Swift, os protocolos são a principal ferramenta de abstração; as classes são usadas com menos frequência.
POP é um paradigma onde protocolos e extensões de protocolo substituem hierarquias profundas de herança. Em vez de uma classe base da qual todas as subclasses herdam, o POP usa composição de protocolos com implementações padrão através de extensão. Isso reduz o acoplamento e melhora a reutilização de código.
Sim, os protocolos Swift suportam herança. protocol SerializableDrawable: Drawable, Codable — um protocolo que combina os requisitos de Drawable e Codable. Um tipo que adota SerializableDrawable deve atender aos requisitos de todos os protocolos na hierarquia. Isso difere da herança de classes — os protocolos não têm um ancestral comum.
some (tipo opaco) garante que uma função retorna um tipo específico em conformidade com o protocolo. any (tipo existencial) permite armazenar qualquer tipo que esteja em conformidade com o protocolo. some é usado para preservar a identidade do tipo, any — para coleções heterogêneas. some apareceu no Swift 5.1, any — no Swift 5.7.
Use is para verificar e as? para converter: if let drawable = object as? Drawable { drawable.draw(in: ctx) }. Em Objective-C, usa-se conformsToProtocol:. Swift também suporta verificação is para protocolos sem tipos associados.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também