O que esconde a palavra-chave open em Swift? Análise para iniciantes
Você já escreveu uma classe em Swift, adicionou public a ela, e depois tentou herdar dela em outro módulo — e recebeu um erro de compilação? Se sim, você não está sozinho. Essa é uma das perguntas mais populares no Stack Overflow entre desenvolvedores Swift iniciantes. Milhares de pessoas tropeçam na mesma pedra: a palavra-chave open.
Neste artigo, vamos entender de uma vez por todas o que é open em Swift, como difere de public, quando deve ser usado e quando — absolutamente não deve. Escreveremos código real, veremos os erros e aprenderemos a corrigi-los. Vamos lá!
Sistema de modificadores de acesso em Swift: breve introdução
Antes de mergulharmos no open, vamos lembrar quais níveis de acesso existem em Swift. São cinco (do mais restrito ao mais aberto):
private— acessível apenas dentro de um único arquivo e uma única declaração (por exemplo, dentro de uma classe).fileprivate— acessível dentro de todo o arquivo.internal— acessível dentro de todo o módulo (este é o nível padrão).public— acessível de outros módulos, mas não é possível herdar ou sobrescrever.open— acessível de outros módulos, é possível herdar e sobrescrever.
A principal questão está na diferença entre public e open. À primeira vista, eles são semelhantes: ambos permitem acessar uma classe, método ou propriedade de outro módulo. Mas há uma diferença fundamental, que vamos analisar com exemplos.
Exemplo: classe public que não pode ser estendida
Imagine que você está escrevendo uma biblioteca (framework) para trabalhar com rede. Você cria uma classe NetworkService e a torna public:
// Módulo: MyNetworkingFrameworkpublic class NetworkService { public func fetchData() { print("Buscando dados da rede...") }}Agora, outro desenvolvedor integra seu framework e quer criar uma classe melhorada baseada nela:
// Módulo: MyAppimport MyNetworkingFramework
// Erro! Cannot inherit from a public classclass MyNetworkService: NetworkService { override func fetchData() { print("Minha busca personalizada...") }}O compilador emitirá um erro. Por quê? Porque public é um acesso somente leitura de outro módulo. Você pode usar uma instância da classe, chamar seus métodos, mas não pode herdar dela. Isso é intencional: o autor da biblioteca quer controlar quais classes podem ser estendidas e quais não.
Solução: usando open
Se o autor da biblioteca quiser permitir herança, ele deve explicitamente usar open:
// Módulo: MyNetworkingFrameworkopen class NetworkService { open func fetchData() { print("Buscando dados da rede...") }}Agora, em outro módulo, é possível herdar e sobrescrever métodos tranquilamente:
// Módulo: MyAppimport MyNetworkingFramework
class MyNetworkService: NetworkService { override func fetchData() { print("Minha busca personalizada com logging extra...") super.fetchData() }}Essa é toda a mágica. A palavra-chave open é a permissão para herança e sobrescrita fora do módulo.
Por que open é importante para a arquitetura?
Os desenvolvedores do Swift e da Apple não introduziram essa diferença à toa. Ela ajuda a projetar APIs robustas e seguras. Imagine que você lança uma biblioteca e todas as classes nela são open.